xref: /openbmc/linux/net/dccp/ccids/ccid3.c (revision c1734376)
17c657876SArnaldo Carvalho de Melo /*
27c657876SArnaldo Carvalho de Melo  *  net/dccp/ccids/ccid3.c
37c657876SArnaldo Carvalho de Melo  *
47c657876SArnaldo Carvalho de Melo  *  Copyright (c) 2005 The University of Waikato, Hamilton, New Zealand.
57c657876SArnaldo Carvalho de Melo  *
67c657876SArnaldo Carvalho de Melo  *  An implementation of the DCCP protocol
77c657876SArnaldo Carvalho de Melo  *
87c657876SArnaldo Carvalho de Melo  *  This code has been developed by the University of Waikato WAND
97c657876SArnaldo Carvalho de Melo  *  research group. For further information please see http://www.wand.net.nz/
107c657876SArnaldo Carvalho de Melo  *  or e-mail Ian McDonald - iam4@cs.waikato.ac.nz
117c657876SArnaldo Carvalho de Melo  *
127c657876SArnaldo Carvalho de Melo  *  This code also uses code from Lulea University, rereleased as GPL by its
137c657876SArnaldo Carvalho de Melo  *  authors:
147c657876SArnaldo Carvalho de Melo  *  Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
157c657876SArnaldo Carvalho de Melo  *
167c657876SArnaldo Carvalho de Melo  *  Changes to meet Linux coding standards, to make it meet latest ccid3 draft
177c657876SArnaldo Carvalho de Melo  *  and to make it work as a loadable module in the DCCP stack written by
187c657876SArnaldo Carvalho de Melo  *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>.
197c657876SArnaldo Carvalho de Melo  *
207c657876SArnaldo Carvalho de Melo  *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
217c657876SArnaldo Carvalho de Melo  *
227c657876SArnaldo Carvalho de Melo  *  This program is free software; you can redistribute it and/or modify
237c657876SArnaldo Carvalho de Melo  *  it under the terms of the GNU General Public License as published by
247c657876SArnaldo Carvalho de Melo  *  the Free Software Foundation; either version 2 of the License, or
257c657876SArnaldo Carvalho de Melo  *  (at your option) any later version.
267c657876SArnaldo Carvalho de Melo  *
277c657876SArnaldo Carvalho de Melo  *  This program is distributed in the hope that it will be useful,
287c657876SArnaldo Carvalho de Melo  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
297c657876SArnaldo Carvalho de Melo  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
307c657876SArnaldo Carvalho de Melo  *  GNU General Public License for more details.
317c657876SArnaldo Carvalho de Melo  *
327c657876SArnaldo Carvalho de Melo  *  You should have received a copy of the GNU General Public License
337c657876SArnaldo Carvalho de Melo  *  along with this program; if not, write to the Free Software
347c657876SArnaldo Carvalho de Melo  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
357c657876SArnaldo Carvalho de Melo  */
367c657876SArnaldo Carvalho de Melo 
378c60f3faSArnaldo Carvalho de Melo #include <linux/config.h>
387c657876SArnaldo Carvalho de Melo #include "../ccid.h"
397c657876SArnaldo Carvalho de Melo #include "../dccp.h"
408c60f3faSArnaldo Carvalho de Melo #include "../packet_history.h"
417c657876SArnaldo Carvalho de Melo #include "ccid3.h"
427c657876SArnaldo Carvalho de Melo 
437c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG
447c657876SArnaldo Carvalho de Melo extern int ccid3_debug;
457c657876SArnaldo Carvalho de Melo 
467c657876SArnaldo Carvalho de Melo #define ccid3_pr_debug(format, a...) \
477c657876SArnaldo Carvalho de Melo 	do { if (ccid3_debug) \
487c657876SArnaldo Carvalho de Melo 		printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
497c657876SArnaldo Carvalho de Melo 	} while (0)
507c657876SArnaldo Carvalho de Melo #else
517c657876SArnaldo Carvalho de Melo #define ccid3_pr_debug(format, a...)
527c657876SArnaldo Carvalho de Melo #endif
537c657876SArnaldo Carvalho de Melo 
547c657876SArnaldo Carvalho de Melo #define TFRC_MIN_PACKET_SIZE	   16
557c657876SArnaldo Carvalho de Melo #define TFRC_STD_PACKET_SIZE	  256
567c657876SArnaldo Carvalho de Melo #define TFRC_MAX_PACKET_SIZE	65535
577c657876SArnaldo Carvalho de Melo 
58cef07fd6SArnaldo Carvalho de Melo #define TFRC_INITIAL_TIMEOUT	   (2 * USEC_PER_SEC)
597c657876SArnaldo Carvalho de Melo /* two seconds as per CCID3 spec 11 */
607c657876SArnaldo Carvalho de Melo 
61cef07fd6SArnaldo Carvalho de Melo #define TFRC_OPSYS_HALF_TIME_GRAN	(USEC_PER_SEC / (2 * HZ))
627c657876SArnaldo Carvalho de Melo /* above is in usecs - half the scheduling granularity as per RFC3448 4.6 */
637c657876SArnaldo Carvalho de Melo 
647c657876SArnaldo Carvalho de Melo #define TFRC_WIN_COUNT_PER_RTT	    4
657c657876SArnaldo Carvalho de Melo #define TFRC_WIN_COUNT_LIMIT	   16
667c657876SArnaldo Carvalho de Melo 
677c657876SArnaldo Carvalho de Melo #define TFRC_MAX_BACK_OFF_TIME	   64
687c657876SArnaldo Carvalho de Melo /* above is in seconds */
697c657876SArnaldo Carvalho de Melo 
707c657876SArnaldo Carvalho de Melo #define TFRC_SMALLEST_P		   40
717c657876SArnaldo Carvalho de Melo 
727c657876SArnaldo Carvalho de Melo #define TFRC_RECV_IVAL_F_LENGTH	    8          /* length(w[]) */
737c657876SArnaldo Carvalho de Melo 
747c657876SArnaldo Carvalho de Melo /* Number of later packets received before one is considered lost */
757c657876SArnaldo Carvalho de Melo #define TFRC_RECV_NUM_LATE_LOSS	3
767c657876SArnaldo Carvalho de Melo 
777c657876SArnaldo Carvalho de Melo enum ccid3_options {
787c657876SArnaldo Carvalho de Melo 	TFRC_OPT_LOSS_EVENT_RATE = 192,
797c657876SArnaldo Carvalho de Melo 	TFRC_OPT_LOSS_INTERVALS	 = 193,
807c657876SArnaldo Carvalho de Melo 	TFRC_OPT_RECEIVE_RATE	 = 194,
817c657876SArnaldo Carvalho de Melo };
827c657876SArnaldo Carvalho de Melo 
837c657876SArnaldo Carvalho de Melo static int ccid3_debug;
847c657876SArnaldo Carvalho de Melo 
858c60f3faSArnaldo Carvalho de Melo struct dccp_tx_hist *ccid3_tx_hist;
868c60f3faSArnaldo Carvalho de Melo struct dccp_rx_hist *ccid3_rx_hist;
878c60f3faSArnaldo Carvalho de Melo 
887c657876SArnaldo Carvalho de Melo static kmem_cache_t *ccid3_loss_interval_hist_slab;
897c657876SArnaldo Carvalho de Melo 
907c657876SArnaldo Carvalho de Melo static inline struct ccid3_loss_interval_hist_entry *ccid3_loss_interval_hist_entry_new(int prio)
917c657876SArnaldo Carvalho de Melo {
927c657876SArnaldo Carvalho de Melo 	return kmem_cache_alloc(ccid3_loss_interval_hist_slab, prio);
937c657876SArnaldo Carvalho de Melo }
947c657876SArnaldo Carvalho de Melo 
957c657876SArnaldo Carvalho de Melo static inline void ccid3_loss_interval_hist_entry_delete(struct ccid3_loss_interval_hist_entry *entry)
967c657876SArnaldo Carvalho de Melo {
977c657876SArnaldo Carvalho de Melo 	if (entry != NULL)
987c657876SArnaldo Carvalho de Melo 		kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
997c657876SArnaldo Carvalho de Melo }
1007c657876SArnaldo Carvalho de Melo 
1017c657876SArnaldo Carvalho de Melo static void ccid3_loss_interval_history_delete(struct list_head *hist)
1027c657876SArnaldo Carvalho de Melo {
1037c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *entry, *next;
1047c657876SArnaldo Carvalho de Melo 
1057c657876SArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, hist, ccid3lih_node) {
1067c657876SArnaldo Carvalho de Melo 		list_del_init(&entry->ccid3lih_node);
1077c657876SArnaldo Carvalho de Melo 		kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
1087c657876SArnaldo Carvalho de Melo 	}
1097c657876SArnaldo Carvalho de Melo }
1107c657876SArnaldo Carvalho de Melo 
1117c657876SArnaldo Carvalho de Melo static int ccid3_init(struct sock *sk)
1127c657876SArnaldo Carvalho de Melo {
1137c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1147c657876SArnaldo Carvalho de Melo 	return 0;
1157c657876SArnaldo Carvalho de Melo }
1167c657876SArnaldo Carvalho de Melo 
1177c657876SArnaldo Carvalho de Melo static void ccid3_exit(struct sock *sk)
1187c657876SArnaldo Carvalho de Melo {
1197c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1207c657876SArnaldo Carvalho de Melo }
1217c657876SArnaldo Carvalho de Melo 
1227c657876SArnaldo Carvalho de Melo /* TFRC sender states */
1237c657876SArnaldo Carvalho de Melo enum ccid3_hc_tx_states {
1247c657876SArnaldo Carvalho de Melo        	TFRC_SSTATE_NO_SENT = 1,
1257c657876SArnaldo Carvalho de Melo 	TFRC_SSTATE_NO_FBACK,
1267c657876SArnaldo Carvalho de Melo 	TFRC_SSTATE_FBACK,
1277c657876SArnaldo Carvalho de Melo 	TFRC_SSTATE_TERM,
1287c657876SArnaldo Carvalho de Melo };
1297c657876SArnaldo Carvalho de Melo 
1307c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG
1317c657876SArnaldo Carvalho de Melo static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
1327c657876SArnaldo Carvalho de Melo {
1337c657876SArnaldo Carvalho de Melo 	static char *ccid3_state_names[] = {
1347c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_NO_SENT]  = "NO_SENT",
1357c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
1367c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_FBACK]    = "FBACK",
1377c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_TERM]     = "TERM",
1387c657876SArnaldo Carvalho de Melo 	};
1397c657876SArnaldo Carvalho de Melo 
1407c657876SArnaldo Carvalho de Melo 	return ccid3_state_names[state];
1417c657876SArnaldo Carvalho de Melo }
1427c657876SArnaldo Carvalho de Melo #endif
1437c657876SArnaldo Carvalho de Melo 
1447c657876SArnaldo Carvalho de Melo static inline void ccid3_hc_tx_set_state(struct sock *sk, enum ccid3_hc_tx_states state)
1457c657876SArnaldo Carvalho de Melo {
1467c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
1477c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1487c657876SArnaldo Carvalho de Melo 	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
1497c657876SArnaldo Carvalho de Melo 
1507c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
1517c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate), ccid3_tx_state_name(state));
1527c657876SArnaldo Carvalho de Melo 	WARN_ON(state == oldstate);
1537c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_state = state;
1547c657876SArnaldo Carvalho de Melo }
1557c657876SArnaldo Carvalho de Melo 
156cef07fd6SArnaldo Carvalho de Melo static void timeval_sub(struct timeval large, struct timeval small,
157cef07fd6SArnaldo Carvalho de Melo 			struct timeval *result)
158cef07fd6SArnaldo Carvalho de Melo {
1597c657876SArnaldo Carvalho de Melo 	result->tv_sec = large.tv_sec-small.tv_sec;
1607c657876SArnaldo Carvalho de Melo 	if (large.tv_usec < small.tv_usec) {
1617c657876SArnaldo Carvalho de Melo 		(result->tv_sec)--;
162cef07fd6SArnaldo Carvalho de Melo 		result->tv_usec = USEC_PER_SEC +
163cef07fd6SArnaldo Carvalho de Melo 				  large.tv_usec - small.tv_usec;
1647c657876SArnaldo Carvalho de Melo 	} else
1657c657876SArnaldo Carvalho de Melo 		result->tv_usec = large.tv_usec-small.tv_usec;
1667c657876SArnaldo Carvalho de Melo }
1677c657876SArnaldo Carvalho de Melo 
168cef07fd6SArnaldo Carvalho de Melo static inline void timeval_fix(struct timeval *tv)
169cef07fd6SArnaldo Carvalho de Melo {
170cef07fd6SArnaldo Carvalho de Melo 	if (tv->tv_usec >= USEC_PER_SEC) {
1717c657876SArnaldo Carvalho de Melo 		tv->tv_sec++;
172cef07fd6SArnaldo Carvalho de Melo 		tv->tv_usec -= USEC_PER_SEC;
1737c657876SArnaldo Carvalho de Melo 	}
1747c657876SArnaldo Carvalho de Melo }
1757c657876SArnaldo Carvalho de Melo 
1767c657876SArnaldo Carvalho de Melo /* returns the difference in usecs between timeval passed in and current time */
1777c657876SArnaldo Carvalho de Melo static inline u32 now_delta(struct timeval tv) {
1787c657876SArnaldo Carvalho de Melo 	struct timeval now;
1797c657876SArnaldo Carvalho de Melo 
1807c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
1817c657876SArnaldo Carvalho de Melo 	return ((now.tv_sec-tv.tv_sec)*1000000+now.tv_usec-tv.tv_usec);
1827c657876SArnaldo Carvalho de Melo }
1837c657876SArnaldo Carvalho de Melo 
1847c657876SArnaldo Carvalho de Melo #define CALCX_ARRSIZE 500
1857c657876SArnaldo Carvalho de Melo 
1867c657876SArnaldo Carvalho de Melo #define CALCX_SPLIT 50000
1877c657876SArnaldo Carvalho de Melo /* equivalent to 0.05 */
1887c657876SArnaldo Carvalho de Melo 
1897c657876SArnaldo Carvalho de Melo static const u32 calcx_lookup[CALCX_ARRSIZE][2] = {
1907c657876SArnaldo Carvalho de Melo 	{ 37172 , 8172 },
1917c657876SArnaldo Carvalho de Melo 	{ 53499 , 11567 },
1927c657876SArnaldo Carvalho de Melo 	{ 66664 , 14180 },
1937c657876SArnaldo Carvalho de Melo 	{ 78298 , 16388 },
1947c657876SArnaldo Carvalho de Melo 	{ 89021 , 18339 },
1957c657876SArnaldo Carvalho de Melo 	{ 99147 , 20108 },
1967c657876SArnaldo Carvalho de Melo 	{ 108858 , 21738 },
1977c657876SArnaldo Carvalho de Melo 	{ 118273 , 23260 },
1987c657876SArnaldo Carvalho de Melo 	{ 127474 , 24693 },
1997c657876SArnaldo Carvalho de Melo 	{ 136520 , 26052 },
2007c657876SArnaldo Carvalho de Melo 	{ 145456 , 27348 },
2017c657876SArnaldo Carvalho de Melo 	{ 154316 , 28589 },
2027c657876SArnaldo Carvalho de Melo 	{ 163130 , 29783 },
2037c657876SArnaldo Carvalho de Melo 	{ 171919 , 30935 },
2047c657876SArnaldo Carvalho de Melo 	{ 180704 , 32049 },
2057c657876SArnaldo Carvalho de Melo 	{ 189502 , 33130 },
2067c657876SArnaldo Carvalho de Melo 	{ 198328 , 34180 },
2077c657876SArnaldo Carvalho de Melo 	{ 207194 , 35202 },
2087c657876SArnaldo Carvalho de Melo 	{ 216114 , 36198 },
2097c657876SArnaldo Carvalho de Melo 	{ 225097 , 37172 },
2107c657876SArnaldo Carvalho de Melo 	{ 234153 , 38123 },
2117c657876SArnaldo Carvalho de Melo 	{ 243294 , 39055 },
2127c657876SArnaldo Carvalho de Melo 	{ 252527 , 39968 },
2137c657876SArnaldo Carvalho de Melo 	{ 261861 , 40864 },
2147c657876SArnaldo Carvalho de Melo 	{ 271305 , 41743 },
2157c657876SArnaldo Carvalho de Melo 	{ 280866 , 42607 },
2167c657876SArnaldo Carvalho de Melo 	{ 290553 , 43457 },
2177c657876SArnaldo Carvalho de Melo 	{ 300372 , 44293 },
2187c657876SArnaldo Carvalho de Melo 	{ 310333 , 45117 },
2197c657876SArnaldo Carvalho de Melo 	{ 320441 , 45929 },
2207c657876SArnaldo Carvalho de Melo 	{ 330705 , 46729 },
2217c657876SArnaldo Carvalho de Melo 	{ 341131 , 47518 },
2227c657876SArnaldo Carvalho de Melo 	{ 351728 , 48297 },
2237c657876SArnaldo Carvalho de Melo 	{ 362501 , 49066 },
2247c657876SArnaldo Carvalho de Melo 	{ 373460 , 49826 },
2257c657876SArnaldo Carvalho de Melo 	{ 384609 , 50577 },
2267c657876SArnaldo Carvalho de Melo 	{ 395958 , 51320 },
2277c657876SArnaldo Carvalho de Melo 	{ 407513 , 52054 },
2287c657876SArnaldo Carvalho de Melo 	{ 419281 , 52780 },
2297c657876SArnaldo Carvalho de Melo 	{ 431270 , 53499 },
2307c657876SArnaldo Carvalho de Melo 	{ 443487 , 54211 },
2317c657876SArnaldo Carvalho de Melo 	{ 455940 , 54916 },
2327c657876SArnaldo Carvalho de Melo 	{ 468635 , 55614 },
2337c657876SArnaldo Carvalho de Melo 	{ 481581 , 56306 },
2347c657876SArnaldo Carvalho de Melo 	{ 494785 , 56991 },
2357c657876SArnaldo Carvalho de Melo 	{ 508254 , 57671 },
2367c657876SArnaldo Carvalho de Melo 	{ 521996 , 58345 },
2377c657876SArnaldo Carvalho de Melo 	{ 536019 , 59014 },
2387c657876SArnaldo Carvalho de Melo 	{ 550331 , 59677 },
2397c657876SArnaldo Carvalho de Melo 	{ 564939 , 60335 },
2407c657876SArnaldo Carvalho de Melo 	{ 579851 , 60988 },
2417c657876SArnaldo Carvalho de Melo 	{ 595075 , 61636 },
2427c657876SArnaldo Carvalho de Melo 	{ 610619 , 62279 },
2437c657876SArnaldo Carvalho de Melo 	{ 626491 , 62918 },
2447c657876SArnaldo Carvalho de Melo 	{ 642700 , 63553 },
2457c657876SArnaldo Carvalho de Melo 	{ 659253 , 64183 },
2467c657876SArnaldo Carvalho de Melo 	{ 676158 , 64809 },
2477c657876SArnaldo Carvalho de Melo 	{ 693424 , 65431 },
2487c657876SArnaldo Carvalho de Melo 	{ 711060 , 66050 },
2497c657876SArnaldo Carvalho de Melo 	{ 729073 , 66664 },
2507c657876SArnaldo Carvalho de Melo 	{ 747472 , 67275 },
2517c657876SArnaldo Carvalho de Melo 	{ 766266 , 67882 },
2527c657876SArnaldo Carvalho de Melo 	{ 785464 , 68486 },
2537c657876SArnaldo Carvalho de Melo 	{ 805073 , 69087 },
2547c657876SArnaldo Carvalho de Melo 	{ 825103 , 69684 },
2557c657876SArnaldo Carvalho de Melo 	{ 845562 , 70278 },
2567c657876SArnaldo Carvalho de Melo 	{ 866460 , 70868 },
2577c657876SArnaldo Carvalho de Melo 	{ 887805 , 71456 },
2587c657876SArnaldo Carvalho de Melo 	{ 909606 , 72041 },
2597c657876SArnaldo Carvalho de Melo 	{ 931873 , 72623 },
2607c657876SArnaldo Carvalho de Melo 	{ 954614 , 73202 },
2617c657876SArnaldo Carvalho de Melo 	{ 977839 , 73778 },
2627c657876SArnaldo Carvalho de Melo 	{ 1001557 , 74352 },
2637c657876SArnaldo Carvalho de Melo 	{ 1025777 , 74923 },
2647c657876SArnaldo Carvalho de Melo 	{ 1050508 , 75492 },
2657c657876SArnaldo Carvalho de Melo 	{ 1075761 , 76058 },
2667c657876SArnaldo Carvalho de Melo 	{ 1101544 , 76621 },
2677c657876SArnaldo Carvalho de Melo 	{ 1127867 , 77183 },
2687c657876SArnaldo Carvalho de Melo 	{ 1154739 , 77741 },
2697c657876SArnaldo Carvalho de Melo 	{ 1182172 , 78298 },
2707c657876SArnaldo Carvalho de Melo 	{ 1210173 , 78852 },
2717c657876SArnaldo Carvalho de Melo 	{ 1238753 , 79405 },
2727c657876SArnaldo Carvalho de Melo 	{ 1267922 , 79955 },
2737c657876SArnaldo Carvalho de Melo 	{ 1297689 , 80503 },
2747c657876SArnaldo Carvalho de Melo 	{ 1328066 , 81049 },
2757c657876SArnaldo Carvalho de Melo 	{ 1359060 , 81593 },
2767c657876SArnaldo Carvalho de Melo 	{ 1390684 , 82135 },
2777c657876SArnaldo Carvalho de Melo 	{ 1422947 , 82675 },
2787c657876SArnaldo Carvalho de Melo 	{ 1455859 , 83213 },
2797c657876SArnaldo Carvalho de Melo 	{ 1489430 , 83750 },
2807c657876SArnaldo Carvalho de Melo 	{ 1523671 , 84284 },
2817c657876SArnaldo Carvalho de Melo 	{ 1558593 , 84817 },
2827c657876SArnaldo Carvalho de Melo 	{ 1594205 , 85348 },
2837c657876SArnaldo Carvalho de Melo 	{ 1630518 , 85878 },
2847c657876SArnaldo Carvalho de Melo 	{ 1667543 , 86406 },
2857c657876SArnaldo Carvalho de Melo 	{ 1705290 , 86932 },
2867c657876SArnaldo Carvalho de Melo 	{ 1743770 , 87457 },
2877c657876SArnaldo Carvalho de Melo 	{ 1782994 , 87980 },
2887c657876SArnaldo Carvalho de Melo 	{ 1822973 , 88501 },
2897c657876SArnaldo Carvalho de Melo 	{ 1863717 , 89021 },
2907c657876SArnaldo Carvalho de Melo 	{ 1905237 , 89540 },
2917c657876SArnaldo Carvalho de Melo 	{ 1947545 , 90057 },
2927c657876SArnaldo Carvalho de Melo 	{ 1990650 , 90573 },
2937c657876SArnaldo Carvalho de Melo 	{ 2034566 , 91087 },
2947c657876SArnaldo Carvalho de Melo 	{ 2079301 , 91600 },
2957c657876SArnaldo Carvalho de Melo 	{ 2124869 , 92111 },
2967c657876SArnaldo Carvalho de Melo 	{ 2171279 , 92622 },
2977c657876SArnaldo Carvalho de Melo 	{ 2218543 , 93131 },
2987c657876SArnaldo Carvalho de Melo 	{ 2266673 , 93639 },
2997c657876SArnaldo Carvalho de Melo 	{ 2315680 , 94145 },
3007c657876SArnaldo Carvalho de Melo 	{ 2365575 , 94650 },
3017c657876SArnaldo Carvalho de Melo 	{ 2416371 , 95154 },
3027c657876SArnaldo Carvalho de Melo 	{ 2468077 , 95657 },
3037c657876SArnaldo Carvalho de Melo 	{ 2520707 , 96159 },
3047c657876SArnaldo Carvalho de Melo 	{ 2574271 , 96660 },
3057c657876SArnaldo Carvalho de Melo 	{ 2628782 , 97159 },
3067c657876SArnaldo Carvalho de Melo 	{ 2684250 , 97658 },
3077c657876SArnaldo Carvalho de Melo 	{ 2740689 , 98155 },
3087c657876SArnaldo Carvalho de Melo 	{ 2798110 , 98651 },
3097c657876SArnaldo Carvalho de Melo 	{ 2856524 , 99147 },
3107c657876SArnaldo Carvalho de Melo 	{ 2915944 , 99641 },
3117c657876SArnaldo Carvalho de Melo 	{ 2976382 , 100134 },
3127c657876SArnaldo Carvalho de Melo 	{ 3037850 , 100626 },
3137c657876SArnaldo Carvalho de Melo 	{ 3100360 , 101117 },
3147c657876SArnaldo Carvalho de Melo 	{ 3163924 , 101608 },
3157c657876SArnaldo Carvalho de Melo 	{ 3228554 , 102097 },
3167c657876SArnaldo Carvalho de Melo 	{ 3294263 , 102586 },
3177c657876SArnaldo Carvalho de Melo 	{ 3361063 , 103073 },
3187c657876SArnaldo Carvalho de Melo 	{ 3428966 , 103560 },
3197c657876SArnaldo Carvalho de Melo 	{ 3497984 , 104045 },
3207c657876SArnaldo Carvalho de Melo 	{ 3568131 , 104530 },
3217c657876SArnaldo Carvalho de Melo 	{ 3639419 , 105014 },
3227c657876SArnaldo Carvalho de Melo 	{ 3711860 , 105498 },
3237c657876SArnaldo Carvalho de Melo 	{ 3785467 , 105980 },
3247c657876SArnaldo Carvalho de Melo 	{ 3860253 , 106462 },
3257c657876SArnaldo Carvalho de Melo 	{ 3936229 , 106942 },
3267c657876SArnaldo Carvalho de Melo 	{ 4013410 , 107422 },
3277c657876SArnaldo Carvalho de Melo 	{ 4091808 , 107902 },
3287c657876SArnaldo Carvalho de Melo 	{ 4171435 , 108380 },
3297c657876SArnaldo Carvalho de Melo 	{ 4252306 , 108858 },
3307c657876SArnaldo Carvalho de Melo 	{ 4334431 , 109335 },
3317c657876SArnaldo Carvalho de Melo 	{ 4417825 , 109811 },
3327c657876SArnaldo Carvalho de Melo 	{ 4502501 , 110287 },
3337c657876SArnaldo Carvalho de Melo 	{ 4588472 , 110762 },
3347c657876SArnaldo Carvalho de Melo 	{ 4675750 , 111236 },
3357c657876SArnaldo Carvalho de Melo 	{ 4764349 , 111709 },
3367c657876SArnaldo Carvalho de Melo 	{ 4854283 , 112182 },
3377c657876SArnaldo Carvalho de Melo 	{ 4945564 , 112654 },
3387c657876SArnaldo Carvalho de Melo 	{ 5038206 , 113126 },
3397c657876SArnaldo Carvalho de Melo 	{ 5132223 , 113597 },
3407c657876SArnaldo Carvalho de Melo 	{ 5227627 , 114067 },
3417c657876SArnaldo Carvalho de Melo 	{ 5324432 , 114537 },
3427c657876SArnaldo Carvalho de Melo 	{ 5422652 , 115006 },
3437c657876SArnaldo Carvalho de Melo 	{ 5522299 , 115474 },
3447c657876SArnaldo Carvalho de Melo 	{ 5623389 , 115942 },
3457c657876SArnaldo Carvalho de Melo 	{ 5725934 , 116409 },
3467c657876SArnaldo Carvalho de Melo 	{ 5829948 , 116876 },
3477c657876SArnaldo Carvalho de Melo 	{ 5935446 , 117342 },
3487c657876SArnaldo Carvalho de Melo 	{ 6042439 , 117808 },
3497c657876SArnaldo Carvalho de Melo 	{ 6150943 , 118273 },
3507c657876SArnaldo Carvalho de Melo 	{ 6260972 , 118738 },
3517c657876SArnaldo Carvalho de Melo 	{ 6372538 , 119202 },
3527c657876SArnaldo Carvalho de Melo 	{ 6485657 , 119665 },
3537c657876SArnaldo Carvalho de Melo 	{ 6600342 , 120128 },
3547c657876SArnaldo Carvalho de Melo 	{ 6716607 , 120591 },
3557c657876SArnaldo Carvalho de Melo 	{ 6834467 , 121053 },
3567c657876SArnaldo Carvalho de Melo 	{ 6953935 , 121514 },
3577c657876SArnaldo Carvalho de Melo 	{ 7075025 , 121976 },
3587c657876SArnaldo Carvalho de Melo 	{ 7197752 , 122436 },
3597c657876SArnaldo Carvalho de Melo 	{ 7322131 , 122896 },
3607c657876SArnaldo Carvalho de Melo 	{ 7448175 , 123356 },
3617c657876SArnaldo Carvalho de Melo 	{ 7575898 , 123815 },
3627c657876SArnaldo Carvalho de Melo 	{ 7705316 , 124274 },
3637c657876SArnaldo Carvalho de Melo 	{ 7836442 , 124733 },
3647c657876SArnaldo Carvalho de Melo 	{ 7969291 , 125191 },
3657c657876SArnaldo Carvalho de Melo 	{ 8103877 , 125648 },
3667c657876SArnaldo Carvalho de Melo 	{ 8240216 , 126105 },
3677c657876SArnaldo Carvalho de Melo 	{ 8378321 , 126562 },
3687c657876SArnaldo Carvalho de Melo 	{ 8518208 , 127018 },
3697c657876SArnaldo Carvalho de Melo 	{ 8659890 , 127474 },
3707c657876SArnaldo Carvalho de Melo 	{ 8803384 , 127930 },
3717c657876SArnaldo Carvalho de Melo 	{ 8948702 , 128385 },
3727c657876SArnaldo Carvalho de Melo 	{ 9095861 , 128840 },
3737c657876SArnaldo Carvalho de Melo 	{ 9244875 , 129294 },
3747c657876SArnaldo Carvalho de Melo 	{ 9395760 , 129748 },
3757c657876SArnaldo Carvalho de Melo 	{ 9548529 , 130202 },
3767c657876SArnaldo Carvalho de Melo 	{ 9703198 , 130655 },
3777c657876SArnaldo Carvalho de Melo 	{ 9859782 , 131108 },
3787c657876SArnaldo Carvalho de Melo 	{ 10018296 , 131561 },
3797c657876SArnaldo Carvalho de Melo 	{ 10178755 , 132014 },
3807c657876SArnaldo Carvalho de Melo 	{ 10341174 , 132466 },
3817c657876SArnaldo Carvalho de Melo 	{ 10505569 , 132917 },
3827c657876SArnaldo Carvalho de Melo 	{ 10671954 , 133369 },
3837c657876SArnaldo Carvalho de Melo 	{ 10840345 , 133820 },
3847c657876SArnaldo Carvalho de Melo 	{ 11010757 , 134271 },
3857c657876SArnaldo Carvalho de Melo 	{ 11183206 , 134721 },
3867c657876SArnaldo Carvalho de Melo 	{ 11357706 , 135171 },
3877c657876SArnaldo Carvalho de Melo 	{ 11534274 , 135621 },
3887c657876SArnaldo Carvalho de Melo 	{ 11712924 , 136071 },
3897c657876SArnaldo Carvalho de Melo 	{ 11893673 , 136520 },
3907c657876SArnaldo Carvalho de Melo 	{ 12076536 , 136969 },
3917c657876SArnaldo Carvalho de Melo 	{ 12261527 , 137418 },
3927c657876SArnaldo Carvalho de Melo 	{ 12448664 , 137867 },
3937c657876SArnaldo Carvalho de Melo 	{ 12637961 , 138315 },
3947c657876SArnaldo Carvalho de Melo 	{ 12829435 , 138763 },
3957c657876SArnaldo Carvalho de Melo 	{ 13023101 , 139211 },
3967c657876SArnaldo Carvalho de Melo 	{ 13218974 , 139658 },
3977c657876SArnaldo Carvalho de Melo 	{ 13417071 , 140106 },
3987c657876SArnaldo Carvalho de Melo 	{ 13617407 , 140553 },
3997c657876SArnaldo Carvalho de Melo 	{ 13819999 , 140999 },
4007c657876SArnaldo Carvalho de Melo 	{ 14024862 , 141446 },
4017c657876SArnaldo Carvalho de Melo 	{ 14232012 , 141892 },
4027c657876SArnaldo Carvalho de Melo 	{ 14441465 , 142339 },
4037c657876SArnaldo Carvalho de Melo 	{ 14653238 , 142785 },
4047c657876SArnaldo Carvalho de Melo 	{ 14867346 , 143230 },
4057c657876SArnaldo Carvalho de Melo 	{ 15083805 , 143676 },
4067c657876SArnaldo Carvalho de Melo 	{ 15302632 , 144121 },
4077c657876SArnaldo Carvalho de Melo 	{ 15523842 , 144566 },
4087c657876SArnaldo Carvalho de Melo 	{ 15747453 , 145011 },
4097c657876SArnaldo Carvalho de Melo 	{ 15973479 , 145456 },
4107c657876SArnaldo Carvalho de Melo 	{ 16201939 , 145900 },
4117c657876SArnaldo Carvalho de Melo 	{ 16432847 , 146345 },
4127c657876SArnaldo Carvalho de Melo 	{ 16666221 , 146789 },
4137c657876SArnaldo Carvalho de Melo 	{ 16902076 , 147233 },
4147c657876SArnaldo Carvalho de Melo 	{ 17140429 , 147677 },
4157c657876SArnaldo Carvalho de Melo 	{ 17381297 , 148121 },
4167c657876SArnaldo Carvalho de Melo 	{ 17624696 , 148564 },
4177c657876SArnaldo Carvalho de Melo 	{ 17870643 , 149007 },
4187c657876SArnaldo Carvalho de Melo 	{ 18119154 , 149451 },
4197c657876SArnaldo Carvalho de Melo 	{ 18370247 , 149894 },
4207c657876SArnaldo Carvalho de Melo 	{ 18623936 , 150336 },
4217c657876SArnaldo Carvalho de Melo 	{ 18880241 , 150779 },
4227c657876SArnaldo Carvalho de Melo 	{ 19139176 , 151222 },
4237c657876SArnaldo Carvalho de Melo 	{ 19400759 , 151664 },
4247c657876SArnaldo Carvalho de Melo 	{ 19665007 , 152107 },
4257c657876SArnaldo Carvalho de Melo 	{ 19931936 , 152549 },
4267c657876SArnaldo Carvalho de Melo 	{ 20201564 , 152991 },
4277c657876SArnaldo Carvalho de Melo 	{ 20473907 , 153433 },
4287c657876SArnaldo Carvalho de Melo 	{ 20748982 , 153875 },
4297c657876SArnaldo Carvalho de Melo 	{ 21026807 , 154316 },
4307c657876SArnaldo Carvalho de Melo 	{ 21307399 , 154758 },
4317c657876SArnaldo Carvalho de Melo 	{ 21590773 , 155199 },
4327c657876SArnaldo Carvalho de Melo 	{ 21876949 , 155641 },
4337c657876SArnaldo Carvalho de Melo 	{ 22165941 , 156082 },
4347c657876SArnaldo Carvalho de Melo 	{ 22457769 , 156523 },
4357c657876SArnaldo Carvalho de Melo 	{ 22752449 , 156964 },
4367c657876SArnaldo Carvalho de Melo 	{ 23049999 , 157405 },
4377c657876SArnaldo Carvalho de Melo 	{ 23350435 , 157846 },
4387c657876SArnaldo Carvalho de Melo 	{ 23653774 , 158287 },
4397c657876SArnaldo Carvalho de Melo 	{ 23960036 , 158727 },
4407c657876SArnaldo Carvalho de Melo 	{ 24269236 , 159168 },
4417c657876SArnaldo Carvalho de Melo 	{ 24581392 , 159608 },
4427c657876SArnaldo Carvalho de Melo 	{ 24896521 , 160049 },
4437c657876SArnaldo Carvalho de Melo 	{ 25214642 , 160489 },
4447c657876SArnaldo Carvalho de Melo 	{ 25535772 , 160929 },
4457c657876SArnaldo Carvalho de Melo 	{ 25859927 , 161370 },
4467c657876SArnaldo Carvalho de Melo 	{ 26187127 , 161810 },
4477c657876SArnaldo Carvalho de Melo 	{ 26517388 , 162250 },
4487c657876SArnaldo Carvalho de Melo 	{ 26850728 , 162690 },
4497c657876SArnaldo Carvalho de Melo 	{ 27187165 , 163130 },
4507c657876SArnaldo Carvalho de Melo 	{ 27526716 , 163569 },
4517c657876SArnaldo Carvalho de Melo 	{ 27869400 , 164009 },
4527c657876SArnaldo Carvalho de Melo 	{ 28215234 , 164449 },
4537c657876SArnaldo Carvalho de Melo 	{ 28564236 , 164889 },
4547c657876SArnaldo Carvalho de Melo 	{ 28916423 , 165328 },
4557c657876SArnaldo Carvalho de Melo 	{ 29271815 , 165768 },
4567c657876SArnaldo Carvalho de Melo 	{ 29630428 , 166208 },
4577c657876SArnaldo Carvalho de Melo 	{ 29992281 , 166647 },
4587c657876SArnaldo Carvalho de Melo 	{ 30357392 , 167087 },
4597c657876SArnaldo Carvalho de Melo 	{ 30725779 , 167526 },
4607c657876SArnaldo Carvalho de Melo 	{ 31097459 , 167965 },
4617c657876SArnaldo Carvalho de Melo 	{ 31472452 , 168405 },
4627c657876SArnaldo Carvalho de Melo 	{ 31850774 , 168844 },
4637c657876SArnaldo Carvalho de Melo 	{ 32232445 , 169283 },
4647c657876SArnaldo Carvalho de Melo 	{ 32617482 , 169723 },
4657c657876SArnaldo Carvalho de Melo 	{ 33005904 , 170162 },
4667c657876SArnaldo Carvalho de Melo 	{ 33397730 , 170601 },
4677c657876SArnaldo Carvalho de Melo 	{ 33792976 , 171041 },
4687c657876SArnaldo Carvalho de Melo 	{ 34191663 , 171480 },
4697c657876SArnaldo Carvalho de Melo 	{ 34593807 , 171919 },
4707c657876SArnaldo Carvalho de Melo 	{ 34999428 , 172358 },
4717c657876SArnaldo Carvalho de Melo 	{ 35408544 , 172797 },
4727c657876SArnaldo Carvalho de Melo 	{ 35821174 , 173237 },
4737c657876SArnaldo Carvalho de Melo 	{ 36237335 , 173676 },
4747c657876SArnaldo Carvalho de Melo 	{ 36657047 , 174115 },
4757c657876SArnaldo Carvalho de Melo 	{ 37080329 , 174554 },
4767c657876SArnaldo Carvalho de Melo 	{ 37507197 , 174993 },
4777c657876SArnaldo Carvalho de Melo 	{ 37937673 , 175433 },
4787c657876SArnaldo Carvalho de Melo 	{ 38371773 , 175872 },
4797c657876SArnaldo Carvalho de Melo 	{ 38809517 , 176311 },
4807c657876SArnaldo Carvalho de Melo 	{ 39250924 , 176750 },
4817c657876SArnaldo Carvalho de Melo 	{ 39696012 , 177190 },
4827c657876SArnaldo Carvalho de Melo 	{ 40144800 , 177629 },
4837c657876SArnaldo Carvalho de Melo 	{ 40597308 , 178068 },
4847c657876SArnaldo Carvalho de Melo 	{ 41053553 , 178507 },
4857c657876SArnaldo Carvalho de Melo 	{ 41513554 , 178947 },
4867c657876SArnaldo Carvalho de Melo 	{ 41977332 , 179386 },
4877c657876SArnaldo Carvalho de Melo 	{ 42444904 , 179825 },
4887c657876SArnaldo Carvalho de Melo 	{ 42916290 , 180265 },
4897c657876SArnaldo Carvalho de Melo 	{ 43391509 , 180704 },
4907c657876SArnaldo Carvalho de Melo 	{ 43870579 , 181144 },
4917c657876SArnaldo Carvalho de Melo 	{ 44353520 , 181583 },
4927c657876SArnaldo Carvalho de Melo 	{ 44840352 , 182023 },
4937c657876SArnaldo Carvalho de Melo 	{ 45331092 , 182462 },
4947c657876SArnaldo Carvalho de Melo 	{ 45825761 , 182902 },
4957c657876SArnaldo Carvalho de Melo 	{ 46324378 , 183342 },
4967c657876SArnaldo Carvalho de Melo 	{ 46826961 , 183781 },
4977c657876SArnaldo Carvalho de Melo 	{ 47333531 , 184221 },
4987c657876SArnaldo Carvalho de Melo 	{ 47844106 , 184661 },
4997c657876SArnaldo Carvalho de Melo 	{ 48358706 , 185101 },
5007c657876SArnaldo Carvalho de Melo 	{ 48877350 , 185541 },
5017c657876SArnaldo Carvalho de Melo 	{ 49400058 , 185981 },
5027c657876SArnaldo Carvalho de Melo 	{ 49926849 , 186421 },
5037c657876SArnaldo Carvalho de Melo 	{ 50457743 , 186861 },
5047c657876SArnaldo Carvalho de Melo 	{ 50992759 , 187301 },
5057c657876SArnaldo Carvalho de Melo 	{ 51531916 , 187741 },
5067c657876SArnaldo Carvalho de Melo 	{ 52075235 , 188181 },
5077c657876SArnaldo Carvalho de Melo 	{ 52622735 , 188622 },
5087c657876SArnaldo Carvalho de Melo 	{ 53174435 , 189062 },
5097c657876SArnaldo Carvalho de Melo 	{ 53730355 , 189502 },
5107c657876SArnaldo Carvalho de Melo 	{ 54290515 , 189943 },
5117c657876SArnaldo Carvalho de Melo 	{ 54854935 , 190383 },
5127c657876SArnaldo Carvalho de Melo 	{ 55423634 , 190824 },
5137c657876SArnaldo Carvalho de Melo 	{ 55996633 , 191265 },
5147c657876SArnaldo Carvalho de Melo 	{ 56573950 , 191706 },
5157c657876SArnaldo Carvalho de Melo 	{ 57155606 , 192146 },
5167c657876SArnaldo Carvalho de Melo 	{ 57741621 , 192587 },
5177c657876SArnaldo Carvalho de Melo 	{ 58332014 , 193028 },
5187c657876SArnaldo Carvalho de Melo 	{ 58926806 , 193470 },
5197c657876SArnaldo Carvalho de Melo 	{ 59526017 , 193911 },
5207c657876SArnaldo Carvalho de Melo 	{ 60129666 , 194352 },
5217c657876SArnaldo Carvalho de Melo 	{ 60737774 , 194793 },
5227c657876SArnaldo Carvalho de Melo 	{ 61350361 , 195235 },
5237c657876SArnaldo Carvalho de Melo 	{ 61967446 , 195677 },
5247c657876SArnaldo Carvalho de Melo 	{ 62589050 , 196118 },
5257c657876SArnaldo Carvalho de Melo 	{ 63215194 , 196560 },
5267c657876SArnaldo Carvalho de Melo 	{ 63845897 , 197002 },
5277c657876SArnaldo Carvalho de Melo 	{ 64481179 , 197444 },
5287c657876SArnaldo Carvalho de Melo 	{ 65121061 , 197886 },
5297c657876SArnaldo Carvalho de Melo 	{ 65765563 , 198328 },
5307c657876SArnaldo Carvalho de Melo 	{ 66414705 , 198770 },
5317c657876SArnaldo Carvalho de Melo 	{ 67068508 , 199213 },
5327c657876SArnaldo Carvalho de Melo 	{ 67726992 , 199655 },
5337c657876SArnaldo Carvalho de Melo 	{ 68390177 , 200098 },
5347c657876SArnaldo Carvalho de Melo 	{ 69058085 , 200540 },
5357c657876SArnaldo Carvalho de Melo 	{ 69730735 , 200983 },
5367c657876SArnaldo Carvalho de Melo 	{ 70408147 , 201426 },
5377c657876SArnaldo Carvalho de Melo 	{ 71090343 , 201869 },
5387c657876SArnaldo Carvalho de Melo 	{ 71777343 , 202312 },
5397c657876SArnaldo Carvalho de Melo 	{ 72469168 , 202755 },
5407c657876SArnaldo Carvalho de Melo 	{ 73165837 , 203199 },
5417c657876SArnaldo Carvalho de Melo 	{ 73867373 , 203642 },
5427c657876SArnaldo Carvalho de Melo 	{ 74573795 , 204086 },
5437c657876SArnaldo Carvalho de Melo 	{ 75285124 , 204529 },
5447c657876SArnaldo Carvalho de Melo 	{ 76001380 , 204973 },
5457c657876SArnaldo Carvalho de Melo 	{ 76722586 , 205417 },
5467c657876SArnaldo Carvalho de Melo 	{ 77448761 , 205861 },
5477c657876SArnaldo Carvalho de Melo 	{ 78179926 , 206306 },
5487c657876SArnaldo Carvalho de Melo 	{ 78916102 , 206750 },
5497c657876SArnaldo Carvalho de Melo 	{ 79657310 , 207194 },
5507c657876SArnaldo Carvalho de Melo 	{ 80403571 , 207639 },
5517c657876SArnaldo Carvalho de Melo 	{ 81154906 , 208084 },
5527c657876SArnaldo Carvalho de Melo 	{ 81911335 , 208529 },
5537c657876SArnaldo Carvalho de Melo 	{ 82672880 , 208974 },
5547c657876SArnaldo Carvalho de Melo 	{ 83439562 , 209419 },
5557c657876SArnaldo Carvalho de Melo 	{ 84211402 , 209864 },
5567c657876SArnaldo Carvalho de Melo 	{ 84988421 , 210309 },
5577c657876SArnaldo Carvalho de Melo 	{ 85770640 , 210755 },
5587c657876SArnaldo Carvalho de Melo 	{ 86558080 , 211201 },
5597c657876SArnaldo Carvalho de Melo 	{ 87350762 , 211647 },
5607c657876SArnaldo Carvalho de Melo 	{ 88148708 , 212093 },
5617c657876SArnaldo Carvalho de Melo 	{ 88951938 , 212539 },
5627c657876SArnaldo Carvalho de Melo 	{ 89760475 , 212985 },
5637c657876SArnaldo Carvalho de Melo 	{ 90574339 , 213432 },
5647c657876SArnaldo Carvalho de Melo 	{ 91393551 , 213878 },
5657c657876SArnaldo Carvalho de Melo 	{ 92218133 , 214325 },
5667c657876SArnaldo Carvalho de Melo 	{ 93048107 , 214772 },
5677c657876SArnaldo Carvalho de Melo 	{ 93883493 , 215219 },
5687c657876SArnaldo Carvalho de Melo 	{ 94724314 , 215666 },
5697c657876SArnaldo Carvalho de Melo 	{ 95570590 , 216114 },
5707c657876SArnaldo Carvalho de Melo 	{ 96422343 , 216561 },
5717c657876SArnaldo Carvalho de Melo 	{ 97279594 , 217009 },
5727c657876SArnaldo Carvalho de Melo 	{ 98142366 , 217457 },
5737c657876SArnaldo Carvalho de Melo 	{ 99010679 , 217905 },
5747c657876SArnaldo Carvalho de Melo 	{ 99884556 , 218353 },
5757c657876SArnaldo Carvalho de Melo 	{ 100764018 , 218801 },
5767c657876SArnaldo Carvalho de Melo 	{ 101649086 , 219250 },
5777c657876SArnaldo Carvalho de Melo 	{ 102539782 , 219698 },
5787c657876SArnaldo Carvalho de Melo 	{ 103436128 , 220147 },
5797c657876SArnaldo Carvalho de Melo 	{ 104338146 , 220596 },
5807c657876SArnaldo Carvalho de Melo 	{ 105245857 , 221046 },
5817c657876SArnaldo Carvalho de Melo 	{ 106159284 , 221495 },
5827c657876SArnaldo Carvalho de Melo 	{ 107078448 , 221945 },
5837c657876SArnaldo Carvalho de Melo 	{ 108003370 , 222394 },
5847c657876SArnaldo Carvalho de Melo 	{ 108934074 , 222844 },
5857c657876SArnaldo Carvalho de Melo 	{ 109870580 , 223294 },
5867c657876SArnaldo Carvalho de Melo 	{ 110812910 , 223745 },
5877c657876SArnaldo Carvalho de Melo 	{ 111761087 , 224195 },
5887c657876SArnaldo Carvalho de Melo 	{ 112715133 , 224646 },
5897c657876SArnaldo Carvalho de Melo 	{ 113675069 , 225097 },
5907c657876SArnaldo Carvalho de Melo 	{ 114640918 , 225548 },
5917c657876SArnaldo Carvalho de Melo 	{ 115612702 , 225999 },
5927c657876SArnaldo Carvalho de Melo 	{ 116590442 , 226450 },
5937c657876SArnaldo Carvalho de Melo 	{ 117574162 , 226902 },
5947c657876SArnaldo Carvalho de Melo 	{ 118563882 , 227353 },
5957c657876SArnaldo Carvalho de Melo 	{ 119559626 , 227805 },
5967c657876SArnaldo Carvalho de Melo 	{ 120561415 , 228258 },
5977c657876SArnaldo Carvalho de Melo 	{ 121569272 , 228710 },
5987c657876SArnaldo Carvalho de Melo 	{ 122583219 , 229162 },
5997c657876SArnaldo Carvalho de Melo 	{ 123603278 , 229615 },
6007c657876SArnaldo Carvalho de Melo 	{ 124629471 , 230068 },
6017c657876SArnaldo Carvalho de Melo 	{ 125661822 , 230521 },
6027c657876SArnaldo Carvalho de Melo 	{ 126700352 , 230974 },
6037c657876SArnaldo Carvalho de Melo 	{ 127745083 , 231428 },
6047c657876SArnaldo Carvalho de Melo 	{ 128796039 , 231882 },
6057c657876SArnaldo Carvalho de Melo 	{ 129853241 , 232336 },
6067c657876SArnaldo Carvalho de Melo 	{ 130916713 , 232790 },
6077c657876SArnaldo Carvalho de Melo 	{ 131986475 , 233244 },
6087c657876SArnaldo Carvalho de Melo 	{ 133062553 , 233699 },
6097c657876SArnaldo Carvalho de Melo 	{ 134144966 , 234153 },
6107c657876SArnaldo Carvalho de Melo 	{ 135233739 , 234608 },
6117c657876SArnaldo Carvalho de Melo 	{ 136328894 , 235064 },
6127c657876SArnaldo Carvalho de Melo 	{ 137430453 , 235519 },
6137c657876SArnaldo Carvalho de Melo 	{ 138538440 , 235975 },
6147c657876SArnaldo Carvalho de Melo 	{ 139652876 , 236430 },
6157c657876SArnaldo Carvalho de Melo 	{ 140773786 , 236886 },
6167c657876SArnaldo Carvalho de Melo 	{ 141901190 , 237343 },
6177c657876SArnaldo Carvalho de Melo 	{ 143035113 , 237799 },
6187c657876SArnaldo Carvalho de Melo 	{ 144175576 , 238256 },
6197c657876SArnaldo Carvalho de Melo 	{ 145322604 , 238713 },
6207c657876SArnaldo Carvalho de Melo 	{ 146476218 , 239170 },
6217c657876SArnaldo Carvalho de Melo 	{ 147636442 , 239627 },
6227c657876SArnaldo Carvalho de Melo 	{ 148803298 , 240085 },
6237c657876SArnaldo Carvalho de Melo 	{ 149976809 , 240542 },
6247c657876SArnaldo Carvalho de Melo 	{ 151156999 , 241000 },
6257c657876SArnaldo Carvalho de Melo 	{ 152343890 , 241459 },
6267c657876SArnaldo Carvalho de Melo 	{ 153537506 , 241917 },
6277c657876SArnaldo Carvalho de Melo 	{ 154737869 , 242376 },
6287c657876SArnaldo Carvalho de Melo 	{ 155945002 , 242835 },
6297c657876SArnaldo Carvalho de Melo 	{ 157158929 , 243294 },
6307c657876SArnaldo Carvalho de Melo 	{ 158379673 , 243753 },
6317c657876SArnaldo Carvalho de Melo 	{ 159607257 , 244213 },
6327c657876SArnaldo Carvalho de Melo 	{ 160841704 , 244673 },
6337c657876SArnaldo Carvalho de Melo 	{ 162083037 , 245133 },
6347c657876SArnaldo Carvalho de Melo 	{ 163331279 , 245593 },
6357c657876SArnaldo Carvalho de Melo 	{ 164586455 , 246054 },
6367c657876SArnaldo Carvalho de Melo 	{ 165848586 , 246514 },
6377c657876SArnaldo Carvalho de Melo 	{ 167117696 , 246975 },
6387c657876SArnaldo Carvalho de Melo 	{ 168393810 , 247437 },
6397c657876SArnaldo Carvalho de Melo 	{ 169676949 , 247898 },
6407c657876SArnaldo Carvalho de Melo 	{ 170967138 , 248360 },
6417c657876SArnaldo Carvalho de Melo 	{ 172264399 , 248822 },
6427c657876SArnaldo Carvalho de Melo 	{ 173568757 , 249284 },
6437c657876SArnaldo Carvalho de Melo 	{ 174880235 , 249747 },
6447c657876SArnaldo Carvalho de Melo 	{ 176198856 , 250209 },
6457c657876SArnaldo Carvalho de Melo 	{ 177524643 , 250672 },
6467c657876SArnaldo Carvalho de Melo 	{ 178857621 , 251136 },
6477c657876SArnaldo Carvalho de Melo 	{ 180197813 , 251599 },
6487c657876SArnaldo Carvalho de Melo 	{ 181545242 , 252063 },
6497c657876SArnaldo Carvalho de Melo 	{ 182899933 , 252527 },
6507c657876SArnaldo Carvalho de Melo 	{ 184261908 , 252991 },
6517c657876SArnaldo Carvalho de Melo 	{ 185631191 , 253456 },
6527c657876SArnaldo Carvalho de Melo 	{ 187007807 , 253920 },
6537c657876SArnaldo Carvalho de Melo 	{ 188391778 , 254385 },
6547c657876SArnaldo Carvalho de Melo 	{ 189783129 , 254851 },
6557c657876SArnaldo Carvalho de Melo 	{ 191181884 , 255316 },
6567c657876SArnaldo Carvalho de Melo 	{ 192588065 , 255782 },
6577c657876SArnaldo Carvalho de Melo 	{ 194001698 , 256248 },
6587c657876SArnaldo Carvalho de Melo 	{ 195422805 , 256714 },
6597c657876SArnaldo Carvalho de Melo 	{ 196851411 , 257181 },
6607c657876SArnaldo Carvalho de Melo 	{ 198287540 , 257648 },
6617c657876SArnaldo Carvalho de Melo 	{ 199731215 , 258115 },
6627c657876SArnaldo Carvalho de Melo 	{ 201182461 , 258582 },
6637c657876SArnaldo Carvalho de Melo 	{ 202641302 , 259050 },
6647c657876SArnaldo Carvalho de Melo 	{ 204107760 , 259518 },
6657c657876SArnaldo Carvalho de Melo 	{ 205581862 , 259986 },
6667c657876SArnaldo Carvalho de Melo 	{ 207063630 , 260454 },
6677c657876SArnaldo Carvalho de Melo 	{ 208553088 , 260923 },
6687c657876SArnaldo Carvalho de Melo 	{ 210050262 , 261392 },
6697c657876SArnaldo Carvalho de Melo 	{ 211555174 , 261861 },
6707c657876SArnaldo Carvalho de Melo 	{ 213067849 , 262331 },
6717c657876SArnaldo Carvalho de Melo 	{ 214588312 , 262800 },
6727c657876SArnaldo Carvalho de Melo 	{ 216116586 , 263270 },
6737c657876SArnaldo Carvalho de Melo 	{ 217652696 , 263741 },
6747c657876SArnaldo Carvalho de Melo 	{ 219196666 , 264211 },
6757c657876SArnaldo Carvalho de Melo 	{ 220748520 , 264682 },
6767c657876SArnaldo Carvalho de Melo 	{ 222308282 , 265153 },
6777c657876SArnaldo Carvalho de Melo 	{ 223875978 , 265625 },
6787c657876SArnaldo Carvalho de Melo 	{ 225451630 , 266097 },
6797c657876SArnaldo Carvalho de Melo 	{ 227035265 , 266569 },
6807c657876SArnaldo Carvalho de Melo 	{ 228626905 , 267041 },
6817c657876SArnaldo Carvalho de Melo 	{ 230226576 , 267514 },
6827c657876SArnaldo Carvalho de Melo 	{ 231834302 , 267986 },
6837c657876SArnaldo Carvalho de Melo 	{ 233450107 , 268460 },
6847c657876SArnaldo Carvalho de Melo 	{ 235074016 , 268933 },
6857c657876SArnaldo Carvalho de Melo 	{ 236706054 , 269407 },
6867c657876SArnaldo Carvalho de Melo 	{ 238346244 , 269881 },
6877c657876SArnaldo Carvalho de Melo 	{ 239994613 , 270355 },
6887c657876SArnaldo Carvalho de Melo 	{ 241651183 , 270830 },
6897c657876SArnaldo Carvalho de Melo 	{ 243315981 , 271305 }
6907c657876SArnaldo Carvalho de Melo };
6917c657876SArnaldo Carvalho de Melo 
6927c657876SArnaldo Carvalho de Melo /* Calculate the send rate as per section 3.1 of RFC3448
6937c657876SArnaldo Carvalho de Melo 
6947c657876SArnaldo Carvalho de Melo Returns send rate in bytes per second
6957c657876SArnaldo Carvalho de Melo 
6967c657876SArnaldo Carvalho de Melo Integer maths and lookups are used as not allowed floating point in kernel
6977c657876SArnaldo Carvalho de Melo 
6987c657876SArnaldo Carvalho de Melo The function for Xcalc as per section 3.1 of RFC3448 is:
6997c657876SArnaldo Carvalho de Melo 
7007c657876SArnaldo Carvalho de Melo X =                            s
7017c657876SArnaldo Carvalho de Melo      -------------------------------------------------------------
7027c657876SArnaldo Carvalho de Melo      R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2)))
7037c657876SArnaldo Carvalho de Melo 
7047c657876SArnaldo Carvalho de Melo where
7057c657876SArnaldo Carvalho de Melo X is the trasmit rate in bytes/second
7067c657876SArnaldo Carvalho de Melo s is the packet size in bytes
7077c657876SArnaldo Carvalho de Melo R is the round trip time in seconds
7087c657876SArnaldo Carvalho de Melo p is the loss event rate, between 0 and 1.0, of the number of loss events
7097c657876SArnaldo Carvalho de Melo   as a fraction of the number of packets transmitted
7107c657876SArnaldo Carvalho de Melo t_RTO is the TCP retransmission timeout value in seconds
7117c657876SArnaldo Carvalho de Melo b is the number of packets acknowledged by a single TCP acknowledgement
7127c657876SArnaldo Carvalho de Melo 
7137c657876SArnaldo Carvalho de Melo we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
7147c657876SArnaldo Carvalho de Melo 
7157c657876SArnaldo Carvalho de Melo X =                            s
7167c657876SArnaldo Carvalho de Melo      -----------------------------------------------------------------------
7177c657876SArnaldo Carvalho de Melo      R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
7187c657876SArnaldo Carvalho de Melo 
7197c657876SArnaldo Carvalho de Melo 
7207c657876SArnaldo Carvalho de Melo which we can break down into:
7217c657876SArnaldo Carvalho de Melo 
7227c657876SArnaldo Carvalho de Melo X =     s
7237c657876SArnaldo Carvalho de Melo      --------
7247c657876SArnaldo Carvalho de Melo      R * f(p)
7257c657876SArnaldo Carvalho de Melo 
7267c657876SArnaldo Carvalho de Melo where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
7277c657876SArnaldo Carvalho de Melo 
7287c657876SArnaldo Carvalho de Melo Function parameters:
7297c657876SArnaldo Carvalho de Melo s - bytes
7307c657876SArnaldo Carvalho de Melo R - RTT in usecs
7317c657876SArnaldo Carvalho de Melo p - loss rate (decimal fraction multiplied by 1,000,000)
7327c657876SArnaldo Carvalho de Melo 
7337c657876SArnaldo Carvalho de Melo Returns Xcalc in bytes per second
7347c657876SArnaldo Carvalho de Melo 
7357c657876SArnaldo Carvalho de Melo DON'T alter this code unless you run test cases against it as the code
7367c657876SArnaldo Carvalho de Melo has been manipulated to stop underflow/overlow.
7377c657876SArnaldo Carvalho de Melo 
7387c657876SArnaldo Carvalho de Melo */
7397c657876SArnaldo Carvalho de Melo static u32 ccid3_calc_x(u16 s, u32 R, u32 p)
7407c657876SArnaldo Carvalho de Melo {
7417c657876SArnaldo Carvalho de Melo 	int index;
7427c657876SArnaldo Carvalho de Melo 	u32 f;
7437c657876SArnaldo Carvalho de Melo 	u64 tmp1, tmp2;
7447c657876SArnaldo Carvalho de Melo 
7457c657876SArnaldo Carvalho de Melo 	if (p < CALCX_SPLIT)
7467c657876SArnaldo Carvalho de Melo 		index = (p / (CALCX_SPLIT / CALCX_ARRSIZE)) - 1;
7477c657876SArnaldo Carvalho de Melo 	else
7487c657876SArnaldo Carvalho de Melo 		index = (p / (1000000 / CALCX_ARRSIZE)) - 1;
7497c657876SArnaldo Carvalho de Melo 
7507c657876SArnaldo Carvalho de Melo 	if (index < 0)
7517c657876SArnaldo Carvalho de Melo 		/* p should be 0 unless there is a bug in my code */
7527c657876SArnaldo Carvalho de Melo 		index = 0;
7537c657876SArnaldo Carvalho de Melo 
7547c657876SArnaldo Carvalho de Melo 	if (R == 0)
7557c657876SArnaldo Carvalho de Melo 		R = 1; /* RTT can't be zero or else divide by zero */
7567c657876SArnaldo Carvalho de Melo 
7577c657876SArnaldo Carvalho de Melo 	BUG_ON(index >= CALCX_ARRSIZE);
7587c657876SArnaldo Carvalho de Melo 
7597c657876SArnaldo Carvalho de Melo 	if (p >= CALCX_SPLIT)
7607c657876SArnaldo Carvalho de Melo 		f = calcx_lookup[index][0];
7617c657876SArnaldo Carvalho de Melo 	else
7627c657876SArnaldo Carvalho de Melo 		f = calcx_lookup[index][1];
7637c657876SArnaldo Carvalho de Melo 
7647c657876SArnaldo Carvalho de Melo 	tmp1 = ((u64)s * 100000000);
7657c657876SArnaldo Carvalho de Melo 	tmp2 = ((u64)R * (u64)f);
7667c657876SArnaldo Carvalho de Melo 	do_div(tmp2,10000);
7677c657876SArnaldo Carvalho de Melo 	do_div(tmp1,tmp2);
7687c657876SArnaldo Carvalho de Melo 	/* don't alter above math unless you test due to overflow on 32 bit */
7697c657876SArnaldo Carvalho de Melo 
7707c657876SArnaldo Carvalho de Melo 	return (u32)tmp1;
7717c657876SArnaldo Carvalho de Melo }
7727c657876SArnaldo Carvalho de Melo 
7737c657876SArnaldo Carvalho de Melo /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
7747c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
7757c657876SArnaldo Carvalho de Melo {
7767c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK)
7777c657876SArnaldo Carvalho de Melo 		return;
7787c657876SArnaldo Carvalho de Melo 	/* if no feedback spec says t_ipi is 1 second (set elsewhere and then
7797c657876SArnaldo Carvalho de Melo 	 * doubles after every no feedback timer (separate function) */
7807c657876SArnaldo Carvalho de Melo 
7817c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x < 10) {
7827c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n");
7837c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 10;
7847c657876SArnaldo Carvalho de Melo 	}
7857c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000)
7867c657876SArnaldo Carvalho de Melo 		/ (hctx->ccid3hctx_x / 10);
7877c657876SArnaldo Carvalho de Melo 	/* reason for above maths with 10 in there is to avoid 32 bit
7887c657876SArnaldo Carvalho de Melo 	 * overflow for jumbo packets */
7897c657876SArnaldo Carvalho de Melo 
7907c657876SArnaldo Carvalho de Melo }
7917c657876SArnaldo Carvalho de Melo 
7927c657876SArnaldo Carvalho de Melo /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
7937c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
7947c657876SArnaldo Carvalho de Melo {
7957c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN);
7967c657876SArnaldo Carvalho de Melo 
7977c657876SArnaldo Carvalho de Melo }
7987c657876SArnaldo Carvalho de Melo 
7997c657876SArnaldo Carvalho de Melo /*
8007c657876SArnaldo Carvalho de Melo  * Update X by
8017c657876SArnaldo Carvalho de Melo  *    If (p > 0)
8027c657876SArnaldo Carvalho de Melo  *       x_calc = calcX(s, R, p);
8037c657876SArnaldo Carvalho de Melo  *       X = max(min(X_calc, 2 * X_recv), s / t_mbi);
8047c657876SArnaldo Carvalho de Melo  *    Else
8057c657876SArnaldo Carvalho de Melo  *       If (now - tld >= R)
8067c657876SArnaldo Carvalho de Melo  *          X = max(min(2 * X, 2 * X_recv), s / R);
8077c657876SArnaldo Carvalho de Melo  *          tld = now;
8087c657876SArnaldo Carvalho de Melo  */
8097c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_update_x(struct sock *sk)
8107c657876SArnaldo Carvalho de Melo {
8117c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
8127c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
8137c657876SArnaldo Carvalho de Melo 
8147c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {  /* to avoid large error in calcX */
8157c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x_calc = ccid3_calc_x(hctx->ccid3hctx_s,
8167c657876SArnaldo Carvalho de Melo 						      hctx->ccid3hctx_rtt,
8177c657876SArnaldo Carvalho de Melo 						      hctx->ccid3hctx_p);
8187c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 2 * hctx->ccid3hctx_x_recv),
8197c657876SArnaldo Carvalho de Melo 					       hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME);
8207c657876SArnaldo Carvalho de Melo 	} else if (now_delta(hctx->ccid3hctx_t_ld) >= hctx->ccid3hctx_rtt) {
8217c657876SArnaldo Carvalho de Melo 		u32 rtt = hctx->ccid3hctx_rtt;
8227c657876SArnaldo Carvalho de Melo 		if (rtt < 10) {
8237c657876SArnaldo Carvalho de Melo 			rtt = 10;
8247c657876SArnaldo Carvalho de Melo 		} /* avoid divide by zero below */
8257c657876SArnaldo Carvalho de Melo 
8267c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, 2 * hctx->ccid3hctx_x),
8277c657876SArnaldo Carvalho de Melo 					(hctx->ccid3hctx_s * 100000) / (rtt / 10));
8287c657876SArnaldo Carvalho de Melo 		/* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */
8297c657876SArnaldo Carvalho de Melo 		do_gettimeofday(&hctx->ccid3hctx_t_ld);
8307c657876SArnaldo Carvalho de Melo 	}
8317c657876SArnaldo Carvalho de Melo 
8327c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x == 0) {
8337c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("ccid3hctx_x = 0!\n");
8347c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 1;
8357c657876SArnaldo Carvalho de Melo 	}
8367c657876SArnaldo Carvalho de Melo }
8377c657876SArnaldo Carvalho de Melo 
8387c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
8397c657876SArnaldo Carvalho de Melo {
8407c657876SArnaldo Carvalho de Melo 	struct sock *sk = (struct sock *)data;
8417c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
8427c657876SArnaldo Carvalho de Melo 	unsigned long next_tmout = 0;
8437c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
8447c657876SArnaldo Carvalho de Melo 	u32 rtt;
8457c657876SArnaldo Carvalho de Melo 
8467c657876SArnaldo Carvalho de Melo 	bh_lock_sock(sk);
8477c657876SArnaldo Carvalho de Melo 	if (sock_owned_by_user(sk)) {
8487c657876SArnaldo Carvalho de Melo 		/* Try again later. */
8497c657876SArnaldo Carvalho de Melo 		/* XXX: set some sensible MIB */
8507c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + HZ / 5);
8517c657876SArnaldo Carvalho de Melo 		goto out;
8527c657876SArnaldo Carvalho de Melo 	}
8537c657876SArnaldo Carvalho de Melo 
8547c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
8557c657876SArnaldo Carvalho de Melo 		       ccid3_tx_state_name(hctx->ccid3hctx_state));
8567c657876SArnaldo Carvalho de Melo 
8577c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x < 10) {
8587c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n");
8597c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 10;
8607c657876SArnaldo Carvalho de Melo 	}
8617c657876SArnaldo Carvalho de Melo 
8627c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
8637c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_TERM:
8647c657876SArnaldo Carvalho de Melo 		goto out;
8657c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
8667c657876SArnaldo Carvalho de Melo 		/* Halve send rate */
8677c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x /= 2;
8687c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME))
8697c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME;
8707c657876SArnaldo Carvalho de Melo 
8717c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d bytes/s\n",
8727c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, ccid3_tx_state_name(hctx->ccid3hctx_state),
8737c657876SArnaldo Carvalho de Melo 			       hctx->ccid3hctx_x);
8747c657876SArnaldo Carvalho de Melo 		next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000)
8757c657876SArnaldo Carvalho de Melo 				/ (hctx->ccid3hctx_x / 10), TFRC_INITIAL_TIMEOUT);
8767c657876SArnaldo Carvalho de Melo 		/* do above maths with 100000 and 10 to prevent overflow on 32 bit */
8777c657876SArnaldo Carvalho de Melo 		/* FIXME - not sure above calculation is correct. See section 5 of CCID3 11
8787c657876SArnaldo Carvalho de Melo 		 * should adjust tx_t_ipi and double that to achieve it really */
8797c657876SArnaldo Carvalho de Melo 		break;
8807c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
8817c657876SArnaldo Carvalho de Melo 		/* Check if IDLE since last timeout and recv rate is less than 4 packets per RTT */
8827c657876SArnaldo Carvalho de Melo 		rtt = hctx->ccid3hctx_rtt;
8837c657876SArnaldo Carvalho de Melo 		if (rtt < 10)
8847c657876SArnaldo Carvalho de Melo 			rtt = 10;
8857c657876SArnaldo Carvalho de Melo 		/* stop divide by zero below */
8867c657876SArnaldo Carvalho de Melo 		if (!hctx->ccid3hctx_idle || (hctx->ccid3hctx_x_recv >=
8877c657876SArnaldo Carvalho de Melo 				4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) {
8887c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", dccp_role(sk), sk,
8897c657876SArnaldo Carvalho de Melo 				       ccid3_tx_state_name(hctx->ccid3hctx_state));
8907c657876SArnaldo Carvalho de Melo 			/* Halve sending rate */
8917c657876SArnaldo Carvalho de Melo 
8927c657876SArnaldo Carvalho de Melo 			/*  If (X_calc > 2 * X_recv)
8937c657876SArnaldo Carvalho de Melo 			 *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
8947c657876SArnaldo Carvalho de Melo 			 *  Else
8957c657876SArnaldo Carvalho de Melo 			 *    X_recv = X_calc / 4;
8967c657876SArnaldo Carvalho de Melo 			 */
8977c657876SArnaldo Carvalho de Melo 			BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && hctx->ccid3hctx_x_calc == 0);
8987c657876SArnaldo Carvalho de Melo 
8997c657876SArnaldo Carvalho de Melo 			/* check also if p is zero -> x_calc is infinity? */
9007c657876SArnaldo Carvalho de Melo 			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
9017c657876SArnaldo Carvalho de Melo 			    hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
9027c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
9037c657876SArnaldo Carvalho de Melo 								    hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
9047c657876SArnaldo Carvalho de Melo 			else
9057c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
9067c657876SArnaldo Carvalho de Melo 
9077c657876SArnaldo Carvalho de Melo 			/* Update sending rate */
9087c657876SArnaldo Carvalho de Melo 			ccid3_hc_tx_update_x(sk);
9097c657876SArnaldo Carvalho de Melo 		}
9107c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x == 0) {
9117c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n");
9127c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = 10;
9137c657876SArnaldo Carvalho de Melo 		}
9147c657876SArnaldo Carvalho de Melo 		/* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
9157c657876SArnaldo Carvalho de Melo 		next_tmout = max_t(u32, inet_csk(sk)->icsk_rto,
9167c657876SArnaldo Carvalho de Melo 				   2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10));
9177c657876SArnaldo Carvalho de Melo 		break;
9187c657876SArnaldo Carvalho de Melo 	default:
9197c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
9207c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
9217c657876SArnaldo Carvalho de Melo 		dump_stack();
9227c657876SArnaldo Carvalho de Melo 		goto out;
9237c657876SArnaldo Carvalho de Melo 	}
9247c657876SArnaldo Carvalho de Melo 
9257c657876SArnaldo Carvalho de Melo 	sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
9267c657876SArnaldo Carvalho de Melo 			jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
9277c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_idle = 1;
9287c657876SArnaldo Carvalho de Melo out:
9297c657876SArnaldo Carvalho de Melo 	bh_unlock_sock(sk);
9307c657876SArnaldo Carvalho de Melo 	sock_put(sk);
9317c657876SArnaldo Carvalho de Melo }
9327c657876SArnaldo Carvalho de Melo 
93327258ee5SArnaldo Carvalho de Melo static int ccid3_hc_tx_send_packet(struct sock *sk,
93427258ee5SArnaldo Carvalho de Melo 				   struct sk_buff *skb, int len)
9357c657876SArnaldo Carvalho de Melo {
9367c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
9377c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
9388c60f3faSArnaldo Carvalho de Melo 	struct dccp_tx_hist_entry *new_packet;
9397c657876SArnaldo Carvalho de Melo 	struct timeval now;
94027258ee5SArnaldo Carvalho de Melo 	long delay;
9417c657876SArnaldo Carvalho de Melo 	int rc = -ENOTCONN;
9427c657876SArnaldo Carvalho de Melo 
9437c657876SArnaldo Carvalho de Melo //	ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len);
9447c657876SArnaldo Carvalho de Melo 	/*
9457c657876SArnaldo Carvalho de Melo 	 * check if pure ACK or Terminating */
9467c657876SArnaldo Carvalho de Melo 	/* XXX: We only call this function for DATA and DATAACK, on, these packets can have
9477c657876SArnaldo Carvalho de Melo 	 * zero length, but why the comment about "pure ACK"?
9487c657876SArnaldo Carvalho de Melo 	 */
9497c657876SArnaldo Carvalho de Melo 	if (hctx == NULL || len == 0 || hctx->ccid3hctx_state == TFRC_SSTATE_TERM)
9507c657876SArnaldo Carvalho de Melo 		goto out;
9517c657876SArnaldo Carvalho de Melo 
9527c657876SArnaldo Carvalho de Melo 	/* See if last packet allocated was not sent */
9538c60f3faSArnaldo Carvalho de Melo 	new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
9548c60f3faSArnaldo Carvalho de Melo 	if (new_packet == NULL || new_packet->dccphtx_sent) {
9558c60f3faSArnaldo Carvalho de Melo 		new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, SLAB_ATOMIC);
9567c657876SArnaldo Carvalho de Melo 
9577c657876SArnaldo Carvalho de Melo 		rc = -ENOBUFS;
9587c657876SArnaldo Carvalho de Melo 		if (new_packet == NULL) {
9597c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, not enough mem to add "
9607c657876SArnaldo Carvalho de Melo 				       "to history, send refused\n", dccp_role(sk), sk);
9617c657876SArnaldo Carvalho de Melo 			goto out;
9627c657876SArnaldo Carvalho de Melo 		}
9637c657876SArnaldo Carvalho de Melo 
9648c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
9657c657876SArnaldo Carvalho de Melo 	}
9667c657876SArnaldo Carvalho de Melo 
9677c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
9687c657876SArnaldo Carvalho de Melo 
9697c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
9707c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
9717c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n", dccp_role(sk), sk,
9727c657876SArnaldo Carvalho de Melo 			       dp->dccps_gss);
9737c657876SArnaldo Carvalho de Melo 
9747c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
9757c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
9767c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
9777c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_last_win_count	 = 0;
9787c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_last_win_count = now;
9797c657876SArnaldo Carvalho de Melo 		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
9807c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT;
9817c657876SArnaldo Carvalho de Melo 
9827c657876SArnaldo Carvalho de Melo 		/* Set nominal send time for initial packet */
9837c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_nom = now;
9847c657876SArnaldo Carvalho de Melo 		(hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
9857c657876SArnaldo Carvalho de Melo 		timeval_fix(&(hctx->ccid3hctx_t_nom));
9867c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_delta(hctx);
9877c657876SArnaldo Carvalho de Melo 		rc = 0;
9887c657876SArnaldo Carvalho de Melo 		break;
9897c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
9907c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
99127258ee5SArnaldo Carvalho de Melo 		delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
99227258ee5SArnaldo Carvalho de Melo 		ccid3_pr_debug("send_packet delay=%ld\n", delay);
99327258ee5SArnaldo Carvalho de Melo 		delay /= -1000;
9947c657876SArnaldo Carvalho de Melo 		/* divide by -1000 is to convert to ms and get sign right */
99527258ee5SArnaldo Carvalho de Melo 		rc = delay > 0 ? -EAGAIN : 0;
9967c657876SArnaldo Carvalho de Melo 		break;
9977c657876SArnaldo Carvalho de Melo 	default:
9987c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
9997c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
10007c657876SArnaldo Carvalho de Melo 		dump_stack();
10017c657876SArnaldo Carvalho de Melo 		rc = -EINVAL;
10027c657876SArnaldo Carvalho de Melo 		break;
10037c657876SArnaldo Carvalho de Melo 	}
10047c657876SArnaldo Carvalho de Melo 
10057c657876SArnaldo Carvalho de Melo 	/* Can we send? if so add options and add to packet history */
10067c657876SArnaldo Carvalho de Melo 	if (rc == 0)
1007c1734376SArnaldo Carvalho de Melo 		new_packet->dccphtx_ccval =
10088c60f3faSArnaldo Carvalho de Melo 			DCCP_SKB_CB(skb)->dccpd_ccval =
10098c60f3faSArnaldo Carvalho de Melo 				hctx->ccid3hctx_last_win_count;
10107c657876SArnaldo Carvalho de Melo out:
10117c657876SArnaldo Carvalho de Melo 	return rc;
10127c657876SArnaldo Carvalho de Melo }
10137c657876SArnaldo Carvalho de Melo 
10147c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
10157c657876SArnaldo Carvalho de Melo {
10167c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
10177c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
10187c657876SArnaldo Carvalho de Melo 	struct timeval now;
10197c657876SArnaldo Carvalho de Melo 
10207c657876SArnaldo Carvalho de Melo //	ccid3_pr_debug("%s, sk=%p, more=%d, len=%d\n", dccp_role(sk), sk, more, len);
10217c657876SArnaldo Carvalho de Melo 	BUG_ON(hctx == NULL);
10227c657876SArnaldo Carvalho de Melo 
10237c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
10247c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n",
10257c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
10267c657876SArnaldo Carvalho de Melo 		return;
10277c657876SArnaldo Carvalho de Melo 	}
10287c657876SArnaldo Carvalho de Melo 
10297c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
10307c657876SArnaldo Carvalho de Melo 
10317c657876SArnaldo Carvalho de Melo 	/* check if we have sent a data packet */
10327c657876SArnaldo Carvalho de Melo 	if (len > 0) {
10337c657876SArnaldo Carvalho de Melo 		unsigned long quarter_rtt;
10348c60f3faSArnaldo Carvalho de Melo 		struct dccp_tx_hist_entry *packet;
10357c657876SArnaldo Carvalho de Melo 
10368c60f3faSArnaldo Carvalho de Melo 		packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
10378c60f3faSArnaldo Carvalho de Melo 		if (packet == NULL) {
10387c657876SArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: packet doesn't exists in history!\n", __FUNCTION__);
10397c657876SArnaldo Carvalho de Melo 			return;
10407c657876SArnaldo Carvalho de Melo 		}
10418c60f3faSArnaldo Carvalho de Melo 		if (packet->dccphtx_sent) {
10427c657876SArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: no unsent packet in history!\n", __FUNCTION__);
10437c657876SArnaldo Carvalho de Melo 			return;
10447c657876SArnaldo Carvalho de Melo 		}
10458c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_tstamp = now;
10468c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_seqno  = dp->dccps_gss;
10478c60f3faSArnaldo Carvalho de Melo #if 0
10488c60f3faSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seqno=%llu inserted!\n",
10498c60f3faSArnaldo Carvalho de Melo 			       dccp_role(sk), sk, packet->dccphtx_seqno);
10508c60f3faSArnaldo Carvalho de Melo #endif
10517c657876SArnaldo Carvalho de Melo 		/*
10527c657876SArnaldo Carvalho de Melo 		 * Check if win_count have changed */
10537c657876SArnaldo Carvalho de Melo 		/* COMPLIANCE_BEGIN
10547c657876SArnaldo Carvalho de Melo 		 * Algorithm in "8.1. Window Counter Valuer" in draft-ietf-dccp-ccid3-11.txt
10557c657876SArnaldo Carvalho de Melo 		 */
10567c657876SArnaldo Carvalho de Melo 		quarter_rtt = now_delta(hctx->ccid3hctx_t_last_win_count) / (hctx->ccid3hctx_rtt / 4);
10577c657876SArnaldo Carvalho de Melo 		if (quarter_rtt > 0) {
10587c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_last_win_count = now;
10597c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_last_win_count	 = (hctx->ccid3hctx_last_win_count +
10607c657876SArnaldo Carvalho de Melo 							    min_t(unsigned long, quarter_rtt, 5)) % 16;
10617c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, window changed from %u to %u!\n",
10627c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
1063c1734376SArnaldo Carvalho de Melo 				       packet->dccphtx_ccval,
10647c657876SArnaldo Carvalho de Melo 				       hctx->ccid3hctx_last_win_count);
10657c657876SArnaldo Carvalho de Melo 		}
10667c657876SArnaldo Carvalho de Melo 		/* COMPLIANCE_END */
10677c657876SArnaldo Carvalho de Melo #if 0
10687c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, packet sent (%llu,%u)\n",
10697c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
10708c60f3faSArnaldo Carvalho de Melo 			       packet->dccphtx_seqno,
1071c1734376SArnaldo Carvalho de Melo 			       packet->dccphtx_ccval);
10727c657876SArnaldo Carvalho de Melo #endif
10737c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_idle = 0;
1074c1734376SArnaldo Carvalho de Melo 		packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
10758c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_sent = 1;
10767c657876SArnaldo Carvalho de Melo 	} else
10777c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
10787c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, dp->dccps_gss);
10797c657876SArnaldo Carvalho de Melo 
10807c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
10817c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
10827c657876SArnaldo Carvalho de Melo 		/* if first wasn't pure ack */
10837c657876SArnaldo Carvalho de Melo 		if (len != 0)
10847c657876SArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: %s, First packet sent is noted as a data packet\n",
10857c657876SArnaldo Carvalho de Melo 			       __FUNCTION__, dccp_role(sk));
10867c657876SArnaldo Carvalho de Melo 		return;
10877c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
10887c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
10897c657876SArnaldo Carvalho de Melo 		if (len > 0) {
10907c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_nom = now;
10917c657876SArnaldo Carvalho de Melo 			ccid3_calc_new_t_ipi(hctx);
10927c657876SArnaldo Carvalho de Melo 			ccid3_calc_new_delta(hctx);
10937c657876SArnaldo Carvalho de Melo 			(hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
10947c657876SArnaldo Carvalho de Melo 			timeval_fix(&(hctx->ccid3hctx_t_nom));
10957c657876SArnaldo Carvalho de Melo 		}
10967c657876SArnaldo Carvalho de Melo 		break;
10977c657876SArnaldo Carvalho de Melo 	default:
10987c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
10997c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
11007c657876SArnaldo Carvalho de Melo 		dump_stack();
11017c657876SArnaldo Carvalho de Melo 		break;
11027c657876SArnaldo Carvalho de Melo 	}
11037c657876SArnaldo Carvalho de Melo }
11047c657876SArnaldo Carvalho de Melo 
11057c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
11067c657876SArnaldo Carvalho de Melo {
11077c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
11087c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
11097c657876SArnaldo Carvalho de Melo 	struct ccid3_options_received *opt_recv;
11108c60f3faSArnaldo Carvalho de Melo 	struct dccp_tx_hist_entry *packet;
11117c657876SArnaldo Carvalho de Melo 	unsigned long next_tmout;
11127c657876SArnaldo Carvalho de Melo 	u16 t_elapsed;
11137c657876SArnaldo Carvalho de Melo 	u32 pinv;
11147c657876SArnaldo Carvalho de Melo 	u32 x_recv;
11157c657876SArnaldo Carvalho de Melo 	u32 r_sample;
11167c657876SArnaldo Carvalho de Melo #if 0
11177c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
11187c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, dccp_state_name(sk->sk_state),
11197c657876SArnaldo Carvalho de Melo 		       skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
11207c657876SArnaldo Carvalho de Melo #endif
11217c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
11227c657876SArnaldo Carvalho de Melo 		return;
11237c657876SArnaldo Carvalho de Melo 
11247c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
11257c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, received a packet when terminating!\n", dccp_role(sk), sk);
11267c657876SArnaldo Carvalho de Melo 		return;
11277c657876SArnaldo Carvalho de Melo 	}
11287c657876SArnaldo Carvalho de Melo 
11297c657876SArnaldo Carvalho de Melo 	/* we are only interested in ACKs */
11307c657876SArnaldo Carvalho de Melo 	if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
11317c657876SArnaldo Carvalho de Melo 	      DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
11327c657876SArnaldo Carvalho de Melo 		return;
11337c657876SArnaldo Carvalho de Melo 
11347c657876SArnaldo Carvalho de Melo 	opt_recv = &hctx->ccid3hctx_options_received;
11357c657876SArnaldo Carvalho de Melo 
11367c657876SArnaldo Carvalho de Melo 	t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
11377c657876SArnaldo Carvalho de Melo 	x_recv = opt_recv->ccid3or_receive_rate;
11387c657876SArnaldo Carvalho de Melo 	pinv = opt_recv->ccid3or_loss_event_rate;
11397c657876SArnaldo Carvalho de Melo 
11407c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
11417c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
11427c657876SArnaldo Carvalho de Melo 		/* FIXME: what to do here? */
11437c657876SArnaldo Carvalho de Melo 		return;
11447c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
11457c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
11467c657876SArnaldo Carvalho de Melo 		/* Calculate new round trip sample by
11477c657876SArnaldo Carvalho de Melo 		 * R_sample = (now - t_recvdata) - t_delay */
11487c657876SArnaldo Carvalho de Melo 		/* get t_recvdata from history */
11498c60f3faSArnaldo Carvalho de Melo 		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
11508c60f3faSArnaldo Carvalho de Melo 						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
11517c657876SArnaldo Carvalho de Melo 		if (packet == NULL) {
11527c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't exist in history!\n",
11537c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk, DCCP_SKB_CB(skb)->dccpd_ack_seq,
11547c657876SArnaldo Carvalho de Melo 				       dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
11557c657876SArnaldo Carvalho de Melo 			return;
11567c657876SArnaldo Carvalho de Melo 		}
11577c657876SArnaldo Carvalho de Melo 
11587c657876SArnaldo Carvalho de Melo 		/* Update RTT */
11598c60f3faSArnaldo Carvalho de Melo 		r_sample = now_delta(packet->dccphtx_tstamp);
11607c657876SArnaldo Carvalho de Melo 		/* FIXME: */
11617c657876SArnaldo Carvalho de Melo 		// r_sample -= usecs_to_jiffies(t_elapsed * 10);
11627c657876SArnaldo Carvalho de Melo 
11637c657876SArnaldo Carvalho de Melo 		/* Update RTT estimate by
11647c657876SArnaldo Carvalho de Melo 		 * If (No feedback recv)
11657c657876SArnaldo Carvalho de Melo 		 *    R = R_sample;
11667c657876SArnaldo Carvalho de Melo 		 * Else
11677c657876SArnaldo Carvalho de Melo 		 *    R = q * R + (1 - q) * R_sample;
11687c657876SArnaldo Carvalho de Melo 		 *
11697c657876SArnaldo Carvalho de Melo 		 * q is a constant, RFC 3448 recomments 0.9
11707c657876SArnaldo Carvalho de Melo 		 */
11717c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
11727c657876SArnaldo Carvalho de Melo 			ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
11737c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = r_sample;
11747c657876SArnaldo Carvalho de Melo 		} else
11757c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + r_sample / 10;
11767c657876SArnaldo Carvalho de Melo 
11777c657876SArnaldo Carvalho de Melo 		/*
11787c657876SArnaldo Carvalho de Melo 		 * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent
11797c657876SArnaldo Carvalho de Melo 		 *      implemention of the new window count.
11807c657876SArnaldo Carvalho de Melo 		 */
11817c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_rtt < 4)
11827c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = 4;
11837c657876SArnaldo Carvalho de Melo 
11847c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, r_sample=%us\n",
11857c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
11867c657876SArnaldo Carvalho de Melo 			       hctx->ccid3hctx_rtt,
11877c657876SArnaldo Carvalho de Melo 			       r_sample);
11887c657876SArnaldo Carvalho de Melo 
11897c657876SArnaldo Carvalho de Melo 		/* Update timeout interval */
1190cef07fd6SArnaldo Carvalho de Melo 		inet_csk(sk)->icsk_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
1191cef07fd6SArnaldo Carvalho de Melo 					       USEC_PER_SEC);
11927c657876SArnaldo Carvalho de Melo 
11937c657876SArnaldo Carvalho de Melo 		/* Update receive rate */
11947c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x_recv = x_recv;   /* x_recv in bytes per second */
11957c657876SArnaldo Carvalho de Melo 
11967c657876SArnaldo Carvalho de Melo 		/* Update loss event rate */
11977c657876SArnaldo Carvalho de Melo 		if (pinv == ~0 || pinv == 0)
11987c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_p = 0;
11997c657876SArnaldo Carvalho de Melo 		else {
12007c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_p = 1000000 / pinv;
12017c657876SArnaldo Carvalho de Melo 
12027c657876SArnaldo Carvalho de Melo 			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
12037c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_p = TFRC_SMALLEST_P;
12047c657876SArnaldo Carvalho de Melo 				ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", dccp_role(sk), sk);
12057c657876SArnaldo Carvalho de Melo 			}
12067c657876SArnaldo Carvalho de Melo 		}
12077c657876SArnaldo Carvalho de Melo 
12087c657876SArnaldo Carvalho de Melo 		/* unschedule no feedback timer */
12097c657876SArnaldo Carvalho de Melo 		sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
12107c657876SArnaldo Carvalho de Melo 
12117c657876SArnaldo Carvalho de Melo 		/* Update sending rate */
12127c657876SArnaldo Carvalho de Melo 		ccid3_hc_tx_update_x(sk);
12137c657876SArnaldo Carvalho de Melo 
12147c657876SArnaldo Carvalho de Melo 		/* Update next send time */
12157c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_t_ipi > (hctx->ccid3hctx_t_nom).tv_usec) {
1216cef07fd6SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_nom.tv_usec += USEC_PER_SEC;
12177c657876SArnaldo Carvalho de Melo 			(hctx->ccid3hctx_t_nom).tv_sec--;
12187c657876SArnaldo Carvalho de Melo 		}
12197c657876SArnaldo Carvalho de Melo 		/* FIXME - if no feedback then t_ipi can go > 1 second */
12207c657876SArnaldo Carvalho de Melo 		(hctx->ccid3hctx_t_nom).tv_usec -= hctx->ccid3hctx_t_ipi;
12217c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_t_ipi(hctx);
12227c657876SArnaldo Carvalho de Melo 		(hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
12237c657876SArnaldo Carvalho de Melo 		timeval_fix(&(hctx->ccid3hctx_t_nom));
12247c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_delta(hctx);
12257c657876SArnaldo Carvalho de Melo 
12267c657876SArnaldo Carvalho de Melo 		/* remove all packets older than the one acked from history */
12278c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_purge_older(ccid3_tx_hist,
12288c60f3faSArnaldo Carvalho de Melo 					 &hctx->ccid3hctx_hist, packet);
12298c60f3faSArnaldo Carvalho de Melo 
12307c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x < 10) {
12317c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx->ccid3hctx_x < 10\n");
12327c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = 10;
12337c657876SArnaldo Carvalho de Melo 		}
12347c657876SArnaldo Carvalho de Melo 		/* to prevent divide by zero below */
12357c657876SArnaldo Carvalho de Melo 
12367c657876SArnaldo Carvalho de Melo 		/* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
12377c657876SArnaldo Carvalho de Melo 		next_tmout = max(inet_csk(sk)->icsk_rto,
12388c60f3faSArnaldo Carvalho de Melo 				 (2 * (hctx->ccid3hctx_s * 100000) /
12398c60f3faSArnaldo Carvalho de Melo 				  (hctx->ccid3hctx_x / 10)));
12407c657876SArnaldo Carvalho de Melo 		/* maths with 100000 and 10 is to prevent overflow with 32 bit */
12417c657876SArnaldo Carvalho de Melo 
12427c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to expire in %lu jiffies (%luus)\n",
12437c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, usecs_to_jiffies(next_tmout), next_tmout);
12447c657876SArnaldo Carvalho de Melo 
12457c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
12467c657876SArnaldo Carvalho de Melo 				jiffies + max_t(u32,1,usecs_to_jiffies(next_tmout)));
12477c657876SArnaldo Carvalho de Melo 
12487c657876SArnaldo Carvalho de Melo 		/* set idle flag */
12497c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_idle = 1;
12507c657876SArnaldo Carvalho de Melo 		break;
12517c657876SArnaldo Carvalho de Melo 	default:
12527c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
12537c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
12547c657876SArnaldo Carvalho de Melo 		dump_stack();
12557c657876SArnaldo Carvalho de Melo 		break;
12567c657876SArnaldo Carvalho de Melo 	}
12577c657876SArnaldo Carvalho de Melo }
12587c657876SArnaldo Carvalho de Melo 
12597c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
12607c657876SArnaldo Carvalho de Melo {
12617c657876SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
12627c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
12637c657876SArnaldo Carvalho de Melo 
12647c657876SArnaldo Carvalho de Melo 	if (hctx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
12657c657876SArnaldo Carvalho de Melo 		return;
12667c657876SArnaldo Carvalho de Melo 
12677c657876SArnaldo Carvalho de Melo 	 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
12687c657876SArnaldo Carvalho de Melo }
12697c657876SArnaldo Carvalho de Melo 
12707c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
12717c657876SArnaldo Carvalho de Melo 				   unsigned char len, u16 idx, unsigned char *value)
12727c657876SArnaldo Carvalho de Melo {
12737c657876SArnaldo Carvalho de Melo 	int rc = 0;
12747c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
12757c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
12767c657876SArnaldo Carvalho de Melo 	struct ccid3_options_received *opt_recv;
12777c657876SArnaldo Carvalho de Melo 
12787c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
12797c657876SArnaldo Carvalho de Melo 		return 0;
12807c657876SArnaldo Carvalho de Melo 
12817c657876SArnaldo Carvalho de Melo 	opt_recv = &hctx->ccid3hctx_options_received;
12827c657876SArnaldo Carvalho de Melo 
12837c657876SArnaldo Carvalho de Melo 	if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
12847c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_seqno		     = dp->dccps_gsr;
12857c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_event_rate    = ~0;
12867c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_idx = 0;
12877c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_len = 0;
12887c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_receive_rate	     = 0;
12897c657876SArnaldo Carvalho de Melo 	}
12907c657876SArnaldo Carvalho de Melo 
12917c657876SArnaldo Carvalho de Melo 	switch (option) {
12927c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_LOSS_EVENT_RATE:
12937c657876SArnaldo Carvalho de Melo 		if (len != 4) {
12947c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_LOSS_EVENT_RATE\n",
12957c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
12967c657876SArnaldo Carvalho de Melo 			rc = -EINVAL;
12977c657876SArnaldo Carvalho de Melo 		} else {
12987c657876SArnaldo Carvalho de Melo 			opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
12997c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
13007c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
13017c657876SArnaldo Carvalho de Melo 				       opt_recv->ccid3or_loss_event_rate);
13027c657876SArnaldo Carvalho de Melo 		}
13037c657876SArnaldo Carvalho de Melo 		break;
13047c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_LOSS_INTERVALS:
13057c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_idx = idx;
13067c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_len = len;
13077c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
13087c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
13097c657876SArnaldo Carvalho de Melo 			       opt_recv->ccid3or_loss_intervals_idx,
13107c657876SArnaldo Carvalho de Melo 			       opt_recv->ccid3or_loss_intervals_len);
13117c657876SArnaldo Carvalho de Melo 		break;
13127c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_RECEIVE_RATE:
13137c657876SArnaldo Carvalho de Melo 		if (len != 4) {
13147c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_RECEIVE_RATE\n",
13157c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
13167c657876SArnaldo Carvalho de Melo 			rc = -EINVAL;
13177c657876SArnaldo Carvalho de Melo 		} else {
13187c657876SArnaldo Carvalho de Melo 			opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
13197c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
13207c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
13217c657876SArnaldo Carvalho de Melo 				       opt_recv->ccid3or_receive_rate);
13227c657876SArnaldo Carvalho de Melo 		}
13237c657876SArnaldo Carvalho de Melo 		break;
13247c657876SArnaldo Carvalho de Melo 	}
13257c657876SArnaldo Carvalho de Melo 
13267c657876SArnaldo Carvalho de Melo 	return rc;
13277c657876SArnaldo Carvalho de Melo }
13287c657876SArnaldo Carvalho de Melo 
13297c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_init(struct sock *sk)
13307c657876SArnaldo Carvalho de Melo {
13317c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13327c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx;
13337c657876SArnaldo Carvalho de Melo 
13347c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
13357c657876SArnaldo Carvalho de Melo 
13367c657876SArnaldo Carvalho de Melo 	hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
13377c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
13387c657876SArnaldo Carvalho de Melo 		return -ENOMEM;
13397c657876SArnaldo Carvalho de Melo 
13407c657876SArnaldo Carvalho de Melo 	memset(hctx, 0, sizeof(*hctx));
13417c657876SArnaldo Carvalho de Melo 
13427c657876SArnaldo Carvalho de Melo 	if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
13437c657876SArnaldo Carvalho de Melo 	    dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
13447c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size;
13457c657876SArnaldo Carvalho de Melo 	else
13467c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
13477c657876SArnaldo Carvalho de Melo 
13487c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_x     = hctx->ccid3hctx_s; /* set transmission rate to 1 packet per second */
13497c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_rtt   = 4; /* See ccid3_hc_tx_packet_sent win_count calculatation */
1350cef07fd6SArnaldo Carvalho de Melo 	inet_csk(sk)->icsk_rto = USEC_PER_SEC;
13517c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
13527c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
13537c657876SArnaldo Carvalho de Melo 	init_timer(&hctx->ccid3hctx_no_feedback_timer);
13547c657876SArnaldo Carvalho de Melo 
13557c657876SArnaldo Carvalho de Melo 	return 0;
13567c657876SArnaldo Carvalho de Melo }
13577c657876SArnaldo Carvalho de Melo 
13587c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_exit(struct sock *sk)
13597c657876SArnaldo Carvalho de Melo {
13607c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13617c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
13627c657876SArnaldo Carvalho de Melo 
13637c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
13647c657876SArnaldo Carvalho de Melo 	BUG_ON(hctx == NULL);
13657c657876SArnaldo Carvalho de Melo 
13667c657876SArnaldo Carvalho de Melo 	ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
13677c657876SArnaldo Carvalho de Melo 	sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
13687c657876SArnaldo Carvalho de Melo 
13697c657876SArnaldo Carvalho de Melo 	/* Empty packet history */
13708c60f3faSArnaldo Carvalho de Melo 	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
13717c657876SArnaldo Carvalho de Melo 
13727c657876SArnaldo Carvalho de Melo 	kfree(dp->dccps_hc_tx_ccid_private);
13737c657876SArnaldo Carvalho de Melo 	dp->dccps_hc_tx_ccid_private = NULL;
13747c657876SArnaldo Carvalho de Melo }
13757c657876SArnaldo Carvalho de Melo 
13767c657876SArnaldo Carvalho de Melo /*
13777c657876SArnaldo Carvalho de Melo  * RX Half Connection methods
13787c657876SArnaldo Carvalho de Melo  */
13797c657876SArnaldo Carvalho de Melo 
13807c657876SArnaldo Carvalho de Melo /* TFRC receiver states */
13817c657876SArnaldo Carvalho de Melo enum ccid3_hc_rx_states {
13827c657876SArnaldo Carvalho de Melo        	TFRC_RSTATE_NO_DATA = 1,
13837c657876SArnaldo Carvalho de Melo 	TFRC_RSTATE_DATA,
13847c657876SArnaldo Carvalho de Melo 	TFRC_RSTATE_TERM    = 127,
13857c657876SArnaldo Carvalho de Melo };
13867c657876SArnaldo Carvalho de Melo 
13877c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG
13887c657876SArnaldo Carvalho de Melo static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
13897c657876SArnaldo Carvalho de Melo {
13907c657876SArnaldo Carvalho de Melo 	static char *ccid3_rx_state_names[] = {
13917c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_NO_DATA] = "NO_DATA",
13927c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_DATA]    = "DATA",
13937c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_TERM]    = "TERM",
13947c657876SArnaldo Carvalho de Melo 	};
13957c657876SArnaldo Carvalho de Melo 
13967c657876SArnaldo Carvalho de Melo 	return ccid3_rx_state_names[state];
13977c657876SArnaldo Carvalho de Melo }
13987c657876SArnaldo Carvalho de Melo #endif
13997c657876SArnaldo Carvalho de Melo 
14007c657876SArnaldo Carvalho de Melo static inline void ccid3_hc_rx_set_state(struct sock *sk, enum ccid3_hc_rx_states state)
14017c657876SArnaldo Carvalho de Melo {
14027c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
14037c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
14047c657876SArnaldo Carvalho de Melo 	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
14057c657876SArnaldo Carvalho de Melo 
14067c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
14077c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate), ccid3_rx_state_name(state));
14087c657876SArnaldo Carvalho de Melo 	WARN_ON(state == oldstate);
14097c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_state = state;
14107c657876SArnaldo Carvalho de Melo }
14117c657876SArnaldo Carvalho de Melo 
14128c60f3faSArnaldo Carvalho de Melo static int ccid3_hc_rx_add_hist(struct sock *sk,
14138c60f3faSArnaldo Carvalho de Melo 				struct dccp_rx_hist_entry *packet)
14147c657876SArnaldo Carvalho de Melo {
14157c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
14167c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
14178c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *iter;
14187c657876SArnaldo Carvalho de Melo 	u8 num_later = 0;
14197c657876SArnaldo Carvalho de Melo 
14208c60f3faSArnaldo Carvalho de Melo 	iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
14218c60f3faSArnaldo Carvalho de Melo 	if (iter == NULL)
14228c60f3faSArnaldo Carvalho de Melo 		dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
14237c657876SArnaldo Carvalho de Melo 	else {
14248c60f3faSArnaldo Carvalho de Melo 		const u64 seqno = packet->dccphrx_seqno;
14258c60f3faSArnaldo Carvalho de Melo 
14268c60f3faSArnaldo Carvalho de Melo 		if (after48(seqno, iter->dccphrx_seqno))
14278c60f3faSArnaldo Carvalho de Melo 			dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
14287c657876SArnaldo Carvalho de Melo 		else {
14298c60f3faSArnaldo Carvalho de Melo 			if (dccp_rx_hist_entry_data_packet(iter))
14307c657876SArnaldo Carvalho de Melo 				num_later = 1;
14317c657876SArnaldo Carvalho de Melo 
14328c60f3faSArnaldo Carvalho de Melo 			list_for_each_entry_continue(iter,
14338c60f3faSArnaldo Carvalho de Melo 						     &hcrx->ccid3hcrx_hist,
14348c60f3faSArnaldo Carvalho de Melo 						     dccphrx_node) {
14358c60f3faSArnaldo Carvalho de Melo 				if (after48(seqno, iter->dccphrx_seqno)) {
14368c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_add_entry(&iter->dccphrx_node,
14378c60f3faSArnaldo Carvalho de Melo 							       packet);
14387c657876SArnaldo Carvalho de Melo 					goto trim_history;
14397c657876SArnaldo Carvalho de Melo 				}
14407c657876SArnaldo Carvalho de Melo 
14418c60f3faSArnaldo Carvalho de Melo 				if (dccp_rx_hist_entry_data_packet(iter))
14427c657876SArnaldo Carvalho de Melo 					num_later++;
14437c657876SArnaldo Carvalho de Melo 
14447c657876SArnaldo Carvalho de Melo 				if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
14458c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_entry_delete(ccid3_rx_hist, packet);
14467c657876SArnaldo Carvalho de Melo 					ccid3_pr_debug("%s, sk=%p, packet(%llu) already lost!\n",
14477c657876SArnaldo Carvalho de Melo 						       dccp_role(sk), sk, seqno);
14487c657876SArnaldo Carvalho de Melo 					return 1;
14497c657876SArnaldo Carvalho de Melo 				}
14507c657876SArnaldo Carvalho de Melo 			}
14517c657876SArnaldo Carvalho de Melo 
14527c657876SArnaldo Carvalho de Melo 			if (num_later < TFRC_RECV_NUM_LATE_LOSS)
14538c60f3faSArnaldo Carvalho de Melo 				dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist,
14548c60f3faSArnaldo Carvalho de Melo 						       packet);
14557c657876SArnaldo Carvalho de Melo 			/* FIXME: else what? should we destroy the packet like above? */
14567c657876SArnaldo Carvalho de Melo 		}
14577c657876SArnaldo Carvalho de Melo 	}
14587c657876SArnaldo Carvalho de Melo 
14597c657876SArnaldo Carvalho de Melo trim_history:
14607c657876SArnaldo Carvalho de Melo 	/* Trim history (remove all packets after the NUM_LATE_LOSS + 1 data packets) */
14617c657876SArnaldo Carvalho de Melo 	num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
14627c657876SArnaldo Carvalho de Melo 
14637c657876SArnaldo Carvalho de Melo 	if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
14648c60f3faSArnaldo Carvalho de Melo 		list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
14658c60f3faSArnaldo Carvalho de Melo 					 dccphrx_node) {
14667c657876SArnaldo Carvalho de Melo 			if (num_later == 0) {
14678c60f3faSArnaldo Carvalho de Melo 				list_del_init(&entry->dccphrx_node);
14688c60f3faSArnaldo Carvalho de Melo 				dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
14698c60f3faSArnaldo Carvalho de Melo 			} else if (dccp_rx_hist_entry_data_packet(entry))
14707c657876SArnaldo Carvalho de Melo 				--num_later;
14717c657876SArnaldo Carvalho de Melo 		}
14727c657876SArnaldo Carvalho de Melo 	} else {
14737c657876SArnaldo Carvalho de Melo 		int step = 0;
14747c657876SArnaldo Carvalho de Melo 		u8 win_count = 0; /* Not needed, but lets shut up gcc */
14757c657876SArnaldo Carvalho de Melo 		int tmp;
14767c657876SArnaldo Carvalho de Melo 		/*
14777c657876SArnaldo Carvalho de Melo 		 * We have no loss interval history so we need at least one
14787c657876SArnaldo Carvalho de Melo 		 * rtt:s of data packets to approximate rtt.
14797c657876SArnaldo Carvalho de Melo 		 */
14808c60f3faSArnaldo Carvalho de Melo 		list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
14818c60f3faSArnaldo Carvalho de Melo 					 dccphrx_node) {
14827c657876SArnaldo Carvalho de Melo 			if (num_later == 0) {
14837c657876SArnaldo Carvalho de Melo 				switch (step) {
14847c657876SArnaldo Carvalho de Melo 				case 0:
14857c657876SArnaldo Carvalho de Melo 					step = 1;
14867c657876SArnaldo Carvalho de Melo 					/* OK, find next data packet */
14877c657876SArnaldo Carvalho de Melo 					num_later = 1;
14887c657876SArnaldo Carvalho de Melo 					break;
14897c657876SArnaldo Carvalho de Melo 				case 1:
14907c657876SArnaldo Carvalho de Melo 					step = 2;
14917c657876SArnaldo Carvalho de Melo 					/* OK, find next data packet */
14927c657876SArnaldo Carvalho de Melo 					num_later = 1;
1493c1734376SArnaldo Carvalho de Melo 					win_count = entry->dccphrx_ccval;
14947c657876SArnaldo Carvalho de Melo 					break;
14957c657876SArnaldo Carvalho de Melo 				case 2:
1496c1734376SArnaldo Carvalho de Melo 					tmp = win_count - entry->dccphrx_ccval;
14977c657876SArnaldo Carvalho de Melo 					if (tmp < 0)
14987c657876SArnaldo Carvalho de Melo 						tmp += TFRC_WIN_COUNT_LIMIT;
14997c657876SArnaldo Carvalho de Melo 					if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
15007c657876SArnaldo Carvalho de Melo 						/* we have found a packet older than one rtt
15017c657876SArnaldo Carvalho de Melo 						 * remove the rest */
15027c657876SArnaldo Carvalho de Melo 						step = 3;
15037c657876SArnaldo Carvalho de Melo 					} else /* OK, find next data packet */
15047c657876SArnaldo Carvalho de Melo 						num_later = 1;
15057c657876SArnaldo Carvalho de Melo 					break;
15067c657876SArnaldo Carvalho de Melo 				case 3:
15078c60f3faSArnaldo Carvalho de Melo 					list_del_init(&entry->dccphrx_node);
15088c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
15097c657876SArnaldo Carvalho de Melo 					break;
15107c657876SArnaldo Carvalho de Melo 				}
15118c60f3faSArnaldo Carvalho de Melo 			} else if (dccp_rx_hist_entry_data_packet(entry))
15127c657876SArnaldo Carvalho de Melo 				--num_later;
15137c657876SArnaldo Carvalho de Melo 		}
15147c657876SArnaldo Carvalho de Melo 	}
15157c657876SArnaldo Carvalho de Melo 
15167c657876SArnaldo Carvalho de Melo 	return 0;
15177c657876SArnaldo Carvalho de Melo }
15187c657876SArnaldo Carvalho de Melo 
15197c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_send_feedback(struct sock *sk)
15207c657876SArnaldo Carvalho de Melo {
15217c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
15227c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
15238c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *packet;
15247c657876SArnaldo Carvalho de Melo 
15257c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
15267c657876SArnaldo Carvalho de Melo 
15277c657876SArnaldo Carvalho de Melo 	switch (hcrx->ccid3hcrx_state) {
15287c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_NO_DATA:
15297c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_x_recv = 0;
15307c657876SArnaldo Carvalho de Melo 		break;
15317c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_DATA: {
15327c657876SArnaldo Carvalho de Melo 		u32 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
15337c657876SArnaldo Carvalho de Melo 
15347c657876SArnaldo Carvalho de Melo 		if (delta == 0)
15357c657876SArnaldo Carvalho de Melo 			delta = 1; /* to prevent divide by zero */
1536cef07fd6SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv *
1537cef07fd6SArnaldo Carvalho de Melo 					  USEC_PER_SEC) / delta;
15387c657876SArnaldo Carvalho de Melo 	}
15397c657876SArnaldo Carvalho de Melo 		break;
15407c657876SArnaldo Carvalho de Melo 	default:
15417c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
15427c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
15437c657876SArnaldo Carvalho de Melo 		dump_stack();
15447c657876SArnaldo Carvalho de Melo 		return;
15457c657876SArnaldo Carvalho de Melo 	}
15467c657876SArnaldo Carvalho de Melo 
15478c60f3faSArnaldo Carvalho de Melo 	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
15487c657876SArnaldo Carvalho de Melo 	if (packet == NULL) {
15497c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n",
15507c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk);
15517c657876SArnaldo Carvalho de Melo 		dump_stack();
15527c657876SArnaldo Carvalho de Melo 		return;
15537c657876SArnaldo Carvalho de Melo 	}
15547c657876SArnaldo Carvalho de Melo 
15557c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&(hcrx->ccid3hcrx_tstamp_last_feedback));
1556c1734376SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_last_counter	     = packet->dccphrx_ccval;
15578c60f3faSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_seqno_last_counter   = packet->dccphrx_seqno;
15587c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_bytes_recv	     = 0;
15597c657876SArnaldo Carvalho de Melo 
15607c657876SArnaldo Carvalho de Melo 	/* Convert to multiples of 10us */
15618c60f3faSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_elapsed_time = now_delta(packet->dccphrx_tstamp) / 10;
15627c657876SArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_p == 0)
15637c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_pinv = ~0;
15647c657876SArnaldo Carvalho de Melo 	else
15657c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
15667c657876SArnaldo Carvalho de Melo 	dccp_send_ack(sk);
15677c657876SArnaldo Carvalho de Melo }
15687c657876SArnaldo Carvalho de Melo 
15697c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
15707c657876SArnaldo Carvalho de Melo {
15717c657876SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
15727c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
15737c657876SArnaldo Carvalho de Melo 
15747c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
15757c657876SArnaldo Carvalho de Melo 		return;
15767c657876SArnaldo Carvalho de Melo 
15777c657876SArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_elapsed_time != 0 && !dccp_packet_without_ack(skb))
15787c657876SArnaldo Carvalho de Melo 		dccp_insert_option_elapsed_time(sk, skb, hcrx->ccid3hcrx_elapsed_time);
15797c657876SArnaldo Carvalho de Melo 
15807c657876SArnaldo Carvalho de Melo 	if (DCCP_SKB_CB(skb)->dccpd_type != DCCP_PKT_DATA) {
15817c657876SArnaldo Carvalho de Melo 		const u32 x_recv = htonl(hcrx->ccid3hcrx_x_recv);
15827c657876SArnaldo Carvalho de Melo 		const u32 pinv   = htonl(hcrx->ccid3hcrx_pinv);
15837c657876SArnaldo Carvalho de Melo 
15847c657876SArnaldo Carvalho de Melo 		dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, &pinv, sizeof(pinv));
15857c657876SArnaldo Carvalho de Melo 		dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, &x_recv, sizeof(x_recv));
15867c657876SArnaldo Carvalho de Melo 	}
15877c657876SArnaldo Carvalho de Melo 
15887c657876SArnaldo Carvalho de Melo 	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
15897c657876SArnaldo Carvalho de Melo }
15907c657876SArnaldo Carvalho de Melo 
15917c657876SArnaldo Carvalho de Melo /* Weights used to calculate loss event rate */
15927c657876SArnaldo Carvalho de Melo /*
15937c657876SArnaldo Carvalho de Melo  * These are integers as per section 8 of RFC3448. We can then divide by 4 *
15947c657876SArnaldo Carvalho de Melo  * when we use it.
15957c657876SArnaldo Carvalho de Melo  */
15967c657876SArnaldo Carvalho de Melo const int ccid3_hc_rx_w[TFRC_RECV_IVAL_F_LENGTH] = { 4, 4, 4, 4, 3, 2, 1, 1, };
15977c657876SArnaldo Carvalho de Melo 
15987c657876SArnaldo Carvalho de Melo /*
15997c657876SArnaldo Carvalho de Melo  * args: fvalue - function value to match
16007c657876SArnaldo Carvalho de Melo  * returns:  p  closest to that value
16017c657876SArnaldo Carvalho de Melo  *
16027c657876SArnaldo Carvalho de Melo  * both fvalue and p are multiplied by 1,000,000 to use ints
16037c657876SArnaldo Carvalho de Melo  */
16047c657876SArnaldo Carvalho de Melo u32 calcx_reverse_lookup(u32 fvalue) {
16057c657876SArnaldo Carvalho de Melo 	int ctr = 0;
16067c657876SArnaldo Carvalho de Melo 	int small;
16077c657876SArnaldo Carvalho de Melo 
16087c657876SArnaldo Carvalho de Melo 	if (fvalue < calcx_lookup[0][1])
16097c657876SArnaldo Carvalho de Melo 		return 0;
16107c657876SArnaldo Carvalho de Melo 	if (fvalue <= calcx_lookup[CALCX_ARRSIZE-1][1])
16117c657876SArnaldo Carvalho de Melo 		small = 1;
16127c657876SArnaldo Carvalho de Melo 	else if (fvalue > calcx_lookup[CALCX_ARRSIZE-1][0])
16137c657876SArnaldo Carvalho de Melo 		return 1000000;
16147c657876SArnaldo Carvalho de Melo 	else
16157c657876SArnaldo Carvalho de Melo 		small = 0;
16167c657876SArnaldo Carvalho de Melo 	while (fvalue > calcx_lookup[ctr][small])
16177c657876SArnaldo Carvalho de Melo 		ctr++;
16187c657876SArnaldo Carvalho de Melo 	if (small)
16197c657876SArnaldo Carvalho de Melo 		return (CALCX_SPLIT * ctr / CALCX_ARRSIZE);
16207c657876SArnaldo Carvalho de Melo 	else
16217c657876SArnaldo Carvalho de Melo 		return (1000000 * ctr / CALCX_ARRSIZE) ;
16227c657876SArnaldo Carvalho de Melo }
16237c657876SArnaldo Carvalho de Melo 
16247c657876SArnaldo Carvalho de Melo /* calculate first loss interval
16257c657876SArnaldo Carvalho de Melo  *
16267c657876SArnaldo Carvalho de Melo  * returns estimated loss interval in usecs */
16277c657876SArnaldo Carvalho de Melo 
16287c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
16297c657876SArnaldo Carvalho de Melo {
16307c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
16317c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
16328c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
16337c657876SArnaldo Carvalho de Melo 	u32 rtt, delta, x_recv, fval, p, tmp2;
16347c657876SArnaldo Carvalho de Melo 	struct timeval tstamp, tmp_tv;
16357c657876SArnaldo Carvalho de Melo 	int interval = 0;
16367c657876SArnaldo Carvalho de Melo 	int win_count = 0;
16377c657876SArnaldo Carvalho de Melo 	int step = 0;
16387c657876SArnaldo Carvalho de Melo 	u64 tmp1;
16397c657876SArnaldo Carvalho de Melo 
16408c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
16418c60f3faSArnaldo Carvalho de Melo 				 dccphrx_node) {
16428c60f3faSArnaldo Carvalho de Melo 		if (dccp_rx_hist_entry_data_packet(entry)) {
16437c657876SArnaldo Carvalho de Melo 			tail = entry;
16447c657876SArnaldo Carvalho de Melo 
16457c657876SArnaldo Carvalho de Melo 			switch (step) {
16467c657876SArnaldo Carvalho de Melo 			case 0:
16478c60f3faSArnaldo Carvalho de Melo 				tstamp	  = entry->dccphrx_tstamp;
1648c1734376SArnaldo Carvalho de Melo 				win_count = entry->dccphrx_ccval;
16497c657876SArnaldo Carvalho de Melo 				step = 1;
16507c657876SArnaldo Carvalho de Melo 				break;
16517c657876SArnaldo Carvalho de Melo 			case 1:
1652c1734376SArnaldo Carvalho de Melo 				interval = win_count - entry->dccphrx_ccval;
16537c657876SArnaldo Carvalho de Melo 				if (interval < 0)
16547c657876SArnaldo Carvalho de Melo 					interval += TFRC_WIN_COUNT_LIMIT;
16557c657876SArnaldo Carvalho de Melo 				if (interval > 4)
16567c657876SArnaldo Carvalho de Melo 					goto found;
16577c657876SArnaldo Carvalho de Melo 				break;
16587c657876SArnaldo Carvalho de Melo 			}
16597c657876SArnaldo Carvalho de Melo 		}
16607c657876SArnaldo Carvalho de Melo 	}
16617c657876SArnaldo Carvalho de Melo 
16627c657876SArnaldo Carvalho de Melo 	if (step == 0) {
16637c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no data packets!\n",
16647c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk);
16657c657876SArnaldo Carvalho de Melo 		return ~0;
16667c657876SArnaldo Carvalho de Melo 	}
16677c657876SArnaldo Carvalho de Melo 
16687c657876SArnaldo Carvalho de Melo 	if (interval == 0) {
16697c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Could not find a win_count interval > 0. Defaulting to 1\n",
16707c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
16717c657876SArnaldo Carvalho de Melo 		interval = 1;
16727c657876SArnaldo Carvalho de Melo 	}
16737c657876SArnaldo Carvalho de Melo found:
16748c60f3faSArnaldo Carvalho de Melo 	timeval_sub(tstamp,tail->dccphrx_tstamp,&tmp_tv);
1675cef07fd6SArnaldo Carvalho de Melo 	rtt = (tmp_tv.tv_sec * USEC_PER_SEC + tmp_tv.tv_usec) * 4 / interval;
16767c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
16777c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, rtt);
16787c657876SArnaldo Carvalho de Melo 	if (rtt == 0)
16797c657876SArnaldo Carvalho de Melo 		rtt = 1;
16807c657876SArnaldo Carvalho de Melo 
16817c657876SArnaldo Carvalho de Melo 	delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
16827c657876SArnaldo Carvalho de Melo 	if (delta == 0)
16837c657876SArnaldo Carvalho de Melo 		delta = 1;
16847c657876SArnaldo Carvalho de Melo 
1685cef07fd6SArnaldo Carvalho de Melo 	x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC) / delta;
16867c657876SArnaldo Carvalho de Melo 
16877c657876SArnaldo Carvalho de Melo 	tmp1 = (u64)x_recv * (u64)rtt;
16887c657876SArnaldo Carvalho de Melo 	do_div(tmp1,10000000);
16897c657876SArnaldo Carvalho de Melo 	tmp2 = (u32)tmp1;
16907c657876SArnaldo Carvalho de Melo 	fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
16917c657876SArnaldo Carvalho de Melo 	/* do not alter order above or you will get overflow on 32 bit */
16927c657876SArnaldo Carvalho de Melo 	p = calcx_reverse_lookup(fval);
16937c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied loss rate=%u\n",\
16947c657876SArnaldo Carvalho de Melo 			dccp_role(sk), sk, x_recv, p);
16957c657876SArnaldo Carvalho de Melo 
16967c657876SArnaldo Carvalho de Melo 	if (p == 0)
16977c657876SArnaldo Carvalho de Melo 		return ~0;
16987c657876SArnaldo Carvalho de Melo 	else
16997c657876SArnaldo Carvalho de Melo 		return 1000000 / p;
17007c657876SArnaldo Carvalho de Melo }
17017c657876SArnaldo Carvalho de Melo 
17027c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
17037c657876SArnaldo Carvalho de Melo {
17047c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
17057c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
17067c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *li_entry;
17077c657876SArnaldo Carvalho de Melo 
17087c657876SArnaldo Carvalho de Melo 	if (seq_loss != DCCP_MAX_SEQNO + 1) {
17097c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seq_loss=%llu, win_loss=%u, packet loss detected\n",
17107c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, seq_loss, win_loss);
17117c657876SArnaldo Carvalho de Melo 
17127c657876SArnaldo Carvalho de Melo 		if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
17137c657876SArnaldo Carvalho de Melo 			struct ccid3_loss_interval_hist_entry *li_tail = NULL;
17147c657876SArnaldo Carvalho de Melo 			int i;
17157c657876SArnaldo Carvalho de Melo 
17167c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, first loss event detected, creating history\n", dccp_role(sk), sk);
17177c657876SArnaldo Carvalho de Melo 			for (i = 0; i <= TFRC_RECV_IVAL_F_LENGTH; ++i) {
17187c657876SArnaldo Carvalho de Melo 				li_entry = ccid3_loss_interval_hist_entry_new(SLAB_ATOMIC);
17197c657876SArnaldo Carvalho de Melo 				if (li_entry == NULL) {
17207c657876SArnaldo Carvalho de Melo 					ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
17217c657876SArnaldo Carvalho de Melo 					ccid3_pr_debug("%s, sk=%p, not enough mem for creating history\n",
17227c657876SArnaldo Carvalho de Melo 						       dccp_role(sk), sk);
17237c657876SArnaldo Carvalho de Melo 					return;
17247c657876SArnaldo Carvalho de Melo 				}
17257c657876SArnaldo Carvalho de Melo 				if (li_tail == NULL)
17267c657876SArnaldo Carvalho de Melo 					li_tail = li_entry;
17277c657876SArnaldo Carvalho de Melo 				list_add(&li_entry->ccid3lih_node, &hcrx->ccid3hcrx_loss_interval_hist);
17287c657876SArnaldo Carvalho de Melo 			}
17297c657876SArnaldo Carvalho de Melo 
17307c657876SArnaldo Carvalho de Melo 			li_entry->ccid3lih_seqno     = seq_loss;
17317c657876SArnaldo Carvalho de Melo 			li_entry->ccid3lih_win_count = win_loss;
17327c657876SArnaldo Carvalho de Melo 
17337c657876SArnaldo Carvalho de Melo 			li_tail->ccid3lih_interval   = ccid3_hc_rx_calc_first_li(sk);
17347c657876SArnaldo Carvalho de Melo 		}
17357c657876SArnaldo Carvalho de Melo 	}
17367c657876SArnaldo Carvalho de Melo 	/* FIXME: find end of interval */
17377c657876SArnaldo Carvalho de Melo }
17387c657876SArnaldo Carvalho de Melo 
17397c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_detect_loss(struct sock *sk)
17407c657876SArnaldo Carvalho de Melo {
17417c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
17427c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
17438c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *packet;
17448c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *a_loss = NULL;
17458c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *b_loss = NULL;
17467c657876SArnaldo Carvalho de Melo 	u64 seq_loss = DCCP_MAX_SEQNO + 1;
17477c657876SArnaldo Carvalho de Melo 	u8 win_loss = 0;
17487c657876SArnaldo Carvalho de Melo 	u8 num_later = TFRC_RECV_NUM_LATE_LOSS;
17497c657876SArnaldo Carvalho de Melo 
17508c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
17518c60f3faSArnaldo Carvalho de Melo 				 dccphrx_node) {
17527c657876SArnaldo Carvalho de Melo 		if (num_later == 0) {
17537c657876SArnaldo Carvalho de Melo 			b_loss = entry;
17547c657876SArnaldo Carvalho de Melo 			break;
17558c60f3faSArnaldo Carvalho de Melo 		} else if (dccp_rx_hist_entry_data_packet(entry))
17567c657876SArnaldo Carvalho de Melo 			--num_later;
17577c657876SArnaldo Carvalho de Melo 	}
17587c657876SArnaldo Carvalho de Melo 
17597c657876SArnaldo Carvalho de Melo 	if (b_loss == NULL)
17607c657876SArnaldo Carvalho de Melo 		goto out_update_li;
17617c657876SArnaldo Carvalho de Melo 
17627c657876SArnaldo Carvalho de Melo 	num_later = 1;
1763757f612eSArnaldo Carvalho de Melo 
17648c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
17658c60f3faSArnaldo Carvalho de Melo 					  dccphrx_node) {
17667c657876SArnaldo Carvalho de Melo 		if (num_later == 0) {
17677c657876SArnaldo Carvalho de Melo 			a_loss = entry;
17687c657876SArnaldo Carvalho de Melo 			break;
17698c60f3faSArnaldo Carvalho de Melo 		} else if (dccp_rx_hist_entry_data_packet(entry))
17707c657876SArnaldo Carvalho de Melo 			--num_later;
17717c657876SArnaldo Carvalho de Melo 	}
17727c657876SArnaldo Carvalho de Melo 
17737c657876SArnaldo Carvalho de Melo 	if (a_loss == NULL) {
17747c657876SArnaldo Carvalho de Melo 		if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
17757c657876SArnaldo Carvalho de Melo 			/* no loss event have occured yet */
17767c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, TODO: find a lost data "
17777c657876SArnaldo Carvalho de Melo 					"packet by comparing to initial seqno\n",
17787c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
17797c657876SArnaldo Carvalho de Melo 			goto out_update_li;
17807c657876SArnaldo Carvalho de Melo 		} else {
17817c657876SArnaldo Carvalho de Melo 			pr_info("%s: %s, sk=%p, ERROR! Less than 4 data packets in history",
17827c657876SArnaldo Carvalho de Melo 				__FUNCTION__, dccp_role(sk), sk);
17837c657876SArnaldo Carvalho de Melo 			return;
17847c657876SArnaldo Carvalho de Melo 		}
17857c657876SArnaldo Carvalho de Melo 	}
17867c657876SArnaldo Carvalho de Melo 
17877c657876SArnaldo Carvalho de Melo 	/* Locate a lost data packet */
17887c657876SArnaldo Carvalho de Melo 	entry = packet = b_loss;
17898c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
17908c60f3faSArnaldo Carvalho de Melo 					  dccphrx_node) {
17918c60f3faSArnaldo Carvalho de Melo 		u64 delta = dccp_delta_seqno(entry->dccphrx_seqno,
17928c60f3faSArnaldo Carvalho de Melo 					     packet->dccphrx_seqno);
17937c657876SArnaldo Carvalho de Melo 
17947c657876SArnaldo Carvalho de Melo 		if (delta != 0) {
17958c60f3faSArnaldo Carvalho de Melo 			if (dccp_rx_hist_entry_data_packet(packet))
17967c657876SArnaldo Carvalho de Melo 				--delta;
17977c657876SArnaldo Carvalho de Melo 			/*
17987c657876SArnaldo Carvalho de Melo 			 * FIXME: check this, probably this % usage is because
17997c657876SArnaldo Carvalho de Melo 			 * in earlier drafts the ndp count was just 8 bits
18007c657876SArnaldo Carvalho de Melo 			 * long, but now it cam be up to 24 bits long.
18017c657876SArnaldo Carvalho de Melo 			 */
18027c657876SArnaldo Carvalho de Melo #if 0
18037c657876SArnaldo Carvalho de Melo 			if (delta % DCCP_NDP_LIMIT !=
18048c60f3faSArnaldo Carvalho de Melo 			    (packet->dccphrx_ndp -
18058c60f3faSArnaldo Carvalho de Melo 			     entry->dccphrx_ndp) % DCCP_NDP_LIMIT)
18067c657876SArnaldo Carvalho de Melo #endif
18078c60f3faSArnaldo Carvalho de Melo 			if (delta !=
18088c60f3faSArnaldo Carvalho de Melo 			     packet->dccphrx_ndp - entry->dccphrx_ndp) {
18098c60f3faSArnaldo Carvalho de Melo 				seq_loss = entry->dccphrx_seqno;
18107c657876SArnaldo Carvalho de Melo 				dccp_inc_seqno(&seq_loss);
18117c657876SArnaldo Carvalho de Melo 			}
18127c657876SArnaldo Carvalho de Melo 		}
18137c657876SArnaldo Carvalho de Melo 		packet = entry;
18147c657876SArnaldo Carvalho de Melo 		if (packet == a_loss)
18157c657876SArnaldo Carvalho de Melo 			break;
18167c657876SArnaldo Carvalho de Melo 	}
18177c657876SArnaldo Carvalho de Melo 
18187c657876SArnaldo Carvalho de Melo 	if (seq_loss != DCCP_MAX_SEQNO + 1)
1819c1734376SArnaldo Carvalho de Melo 		win_loss = a_loss->dccphrx_ccval;
18207c657876SArnaldo Carvalho de Melo 
18217c657876SArnaldo Carvalho de Melo out_update_li:
18227c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
18237c657876SArnaldo Carvalho de Melo }
18247c657876SArnaldo Carvalho de Melo 
18257c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_i_mean(struct sock *sk)
18267c657876SArnaldo Carvalho de Melo {
18277c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
18287c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
18297c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *li_entry, *li_next;
18307c657876SArnaldo Carvalho de Melo 	int i = 0;
18317c657876SArnaldo Carvalho de Melo 	u32 i_tot;
18327c657876SArnaldo Carvalho de Melo 	u32 i_tot0 = 0;
18337c657876SArnaldo Carvalho de Melo 	u32 i_tot1 = 0;
18347c657876SArnaldo Carvalho de Melo 	u32 w_tot  = 0;
18357c657876SArnaldo Carvalho de Melo 
18367c657876SArnaldo Carvalho de Melo 	list_for_each_entry_safe(li_entry, li_next, &hcrx->ccid3hcrx_loss_interval_hist, ccid3lih_node) {
18377c657876SArnaldo Carvalho de Melo 		if (i < TFRC_RECV_IVAL_F_LENGTH) {
18387c657876SArnaldo Carvalho de Melo 			i_tot0 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i];
18397c657876SArnaldo Carvalho de Melo 			w_tot  += ccid3_hc_rx_w[i];
18407c657876SArnaldo Carvalho de Melo 		}
18417c657876SArnaldo Carvalho de Melo 
18427c657876SArnaldo Carvalho de Melo 		if (i != 0)
18437c657876SArnaldo Carvalho de Melo 			i_tot1 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i - 1];
18447c657876SArnaldo Carvalho de Melo 
18457c657876SArnaldo Carvalho de Melo 		if (++i > TFRC_RECV_IVAL_F_LENGTH)
18467c657876SArnaldo Carvalho de Melo 			break;
18477c657876SArnaldo Carvalho de Melo 	}
18487c657876SArnaldo Carvalho de Melo 
18497c657876SArnaldo Carvalho de Melo 	if (i != TFRC_RECV_IVAL_F_LENGTH) {
18507c657876SArnaldo Carvalho de Melo 		pr_info("%s: %s, sk=%p, ERROR! Missing entry in interval history!\n",
18517c657876SArnaldo Carvalho de Melo 			__FUNCTION__, dccp_role(sk), sk);
18527c657876SArnaldo Carvalho de Melo 		return 0;
18537c657876SArnaldo Carvalho de Melo 	}
18547c657876SArnaldo Carvalho de Melo 
18557c657876SArnaldo Carvalho de Melo 	i_tot = max(i_tot0, i_tot1);
18567c657876SArnaldo Carvalho de Melo 
18577c657876SArnaldo Carvalho de Melo 	/* FIXME: Why do we do this? -Ian McDonald */
18587c657876SArnaldo Carvalho de Melo 	if (i_tot * 4 < w_tot)
18597c657876SArnaldo Carvalho de Melo 		i_tot = w_tot * 4;
18607c657876SArnaldo Carvalho de Melo 
18617c657876SArnaldo Carvalho de Melo 	return i_tot * 4 / w_tot;
18627c657876SArnaldo Carvalho de Melo }
18637c657876SArnaldo Carvalho de Melo 
18647c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
18657c657876SArnaldo Carvalho de Melo {
18667c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
18677c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
18688c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *packet;
18697c657876SArnaldo Carvalho de Melo 	struct timeval now;
18707c657876SArnaldo Carvalho de Melo 	u8 win_count;
18717c657876SArnaldo Carvalho de Melo 	u32 p_prev;
18727c657876SArnaldo Carvalho de Melo 	int ins;
18737c657876SArnaldo Carvalho de Melo #if 0
18747c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
18757c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, dccp_state_name(sk->sk_state),
18767c657876SArnaldo Carvalho de Melo 		       skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
18777c657876SArnaldo Carvalho de Melo #endif
18787c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
18797c657876SArnaldo Carvalho de Melo 		return;
18807c657876SArnaldo Carvalho de Melo 
18817c657876SArnaldo Carvalho de Melo 	BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
18827c657876SArnaldo Carvalho de Melo 		 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
18837c657876SArnaldo Carvalho de Melo 
18847c657876SArnaldo Carvalho de Melo 	switch (DCCP_SKB_CB(skb)->dccpd_type) {
18857c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_ACK:
18867c657876SArnaldo Carvalho de Melo 		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
18877c657876SArnaldo Carvalho de Melo 			return;
18887c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_DATAACK:
18897c657876SArnaldo Carvalho de Melo 		if (dp->dccps_options_received.dccpor_timestamp_echo == 0)
18907c657876SArnaldo Carvalho de Melo 			break;
18917c657876SArnaldo Carvalho de Melo 		p_prev = hcrx->ccid3hcrx_rtt;
18927c657876SArnaldo Carvalho de Melo 		do_gettimeofday(&now);
18937c657876SArnaldo Carvalho de Melo 		/* hcrx->ccid3hcrx_rtt = now - dp->dccps_options_received.dccpor_timestamp_echo -
18947c657876SArnaldo Carvalho de Melo 				      usecs_to_jiffies(dp->dccps_options_received.dccpor_elapsed_time * 10);
18957c657876SArnaldo Carvalho de Melo 		FIXME - I think above code is broken - have to look at options more, will also need
18967c657876SArnaldo Carvalho de Melo 		to fix pr_debug below */
18977c657876SArnaldo Carvalho de Melo 		if (p_prev != hcrx->ccid3hcrx_rtt)
18987c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, New RTT estimate=%lu jiffies, tstamp_echo=%u, elapsed time=%u\n",
18997c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk, hcrx->ccid3hcrx_rtt,
19007c657876SArnaldo Carvalho de Melo 				       dp->dccps_options_received.dccpor_timestamp_echo,
19017c657876SArnaldo Carvalho de Melo 				       dp->dccps_options_received.dccpor_elapsed_time);
19027c657876SArnaldo Carvalho de Melo 		break;
19037c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_DATA:
19047c657876SArnaldo Carvalho de Melo 		break;
19057c657876SArnaldo Carvalho de Melo 	default:
19067c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n",
19077c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
19087c657876SArnaldo Carvalho de Melo 			       dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
19097c657876SArnaldo Carvalho de Melo 		return;
19107c657876SArnaldo Carvalho de Melo 	}
19117c657876SArnaldo Carvalho de Melo 
19128c60f3faSArnaldo Carvalho de Melo 	packet = dccp_rx_hist_entry_new(ccid3_rx_hist,
19138c60f3faSArnaldo Carvalho de Melo 					dp->dccps_options_received.dccpor_ndp,
19148c60f3faSArnaldo Carvalho de Melo 					skb, SLAB_ATOMIC);
19157c657876SArnaldo Carvalho de Melo 	if (packet == NULL) {
19167c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet to history (consider it lost)!",
19177c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
19187c657876SArnaldo Carvalho de Melo 		return;
19197c657876SArnaldo Carvalho de Melo 	}
19207c657876SArnaldo Carvalho de Melo 
1921c1734376SArnaldo Carvalho de Melo 	win_count = packet->dccphrx_ccval;
19227c657876SArnaldo Carvalho de Melo 
19237c657876SArnaldo Carvalho de Melo 	ins = ccid3_hc_rx_add_hist(sk, packet);
19247c657876SArnaldo Carvalho de Melo 
19257c657876SArnaldo Carvalho de Melo 	if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
19267c657876SArnaldo Carvalho de Melo 		return;
19277c657876SArnaldo Carvalho de Melo 
19287c657876SArnaldo Carvalho de Melo 	switch (hcrx->ccid3hcrx_state) {
19297c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_NO_DATA:
19307c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial feedback\n",
19317c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb);
19327c657876SArnaldo Carvalho de Melo 		ccid3_hc_rx_send_feedback(sk);
19337c657876SArnaldo Carvalho de Melo 		ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
19347c657876SArnaldo Carvalho de Melo 		return;
19357c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_DATA:
19367c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_bytes_recv += skb->len - dccp_hdr(skb)->dccph_doff * 4;
19377c657876SArnaldo Carvalho de Melo 		if (ins == 0) {
19387c657876SArnaldo Carvalho de Melo 			do_gettimeofday(&now);
19397c657876SArnaldo Carvalho de Melo 			if ((now_delta(hcrx->ccid3hcrx_tstamp_last_ack)) >= hcrx->ccid3hcrx_rtt) {
19407c657876SArnaldo Carvalho de Melo 				hcrx->ccid3hcrx_tstamp_last_ack = now;
19417c657876SArnaldo Carvalho de Melo 				ccid3_hc_rx_send_feedback(sk);
19427c657876SArnaldo Carvalho de Melo 			}
19437c657876SArnaldo Carvalho de Melo 			return;
19447c657876SArnaldo Carvalho de Melo 		}
19457c657876SArnaldo Carvalho de Melo 		break;
19467c657876SArnaldo Carvalho de Melo 	default:
19477c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
19487c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
19497c657876SArnaldo Carvalho de Melo 		dump_stack();
19507c657876SArnaldo Carvalho de Melo 		return;
19517c657876SArnaldo Carvalho de Melo 	}
19527c657876SArnaldo Carvalho de Melo 
19537c657876SArnaldo Carvalho de Melo 	/* Dealing with packet loss */
19547c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p(%s), skb=%p, data loss! Reacting...\n",
19557c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, dccp_state_name(sk->sk_state), skb);
19567c657876SArnaldo Carvalho de Melo 
19577c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_detect_loss(sk);
19587c657876SArnaldo Carvalho de Melo 	p_prev = hcrx->ccid3hcrx_p;
19597c657876SArnaldo Carvalho de Melo 
19607c657876SArnaldo Carvalho de Melo 	/* Calculate loss event rate */
19617c657876SArnaldo Carvalho de Melo 	if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist))
19627c657876SArnaldo Carvalho de Melo 		/* Scaling up by 1000000 as fixed decimal */
19637c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_p = 1000000 / ccid3_hc_rx_calc_i_mean(sk);
19647c657876SArnaldo Carvalho de Melo 
19657c657876SArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_p > p_prev) {
19667c657876SArnaldo Carvalho de Melo 		ccid3_hc_rx_send_feedback(sk);
19677c657876SArnaldo Carvalho de Melo 		return;
19687c657876SArnaldo Carvalho de Melo 	}
19697c657876SArnaldo Carvalho de Melo }
19707c657876SArnaldo Carvalho de Melo 
19717c657876SArnaldo Carvalho de Melo static int ccid3_hc_rx_init(struct sock *sk)
19727c657876SArnaldo Carvalho de Melo {
19737c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
19747c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx;
19757c657876SArnaldo Carvalho de Melo 
19767c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
19777c657876SArnaldo Carvalho de Melo 
19787c657876SArnaldo Carvalho de Melo 	hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx), gfp_any());
19797c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
19807c657876SArnaldo Carvalho de Melo 		return -ENOMEM;
19817c657876SArnaldo Carvalho de Melo 
19827c657876SArnaldo Carvalho de Melo 	memset(hcrx, 0, sizeof(*hcrx));
19837c657876SArnaldo Carvalho de Melo 
19847c657876SArnaldo Carvalho de Melo 	if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
19857c657876SArnaldo Carvalho de Melo 	    dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
19867c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size;
19877c657876SArnaldo Carvalho de Melo 	else
19887c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
19897c657876SArnaldo Carvalho de Melo 
19907c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
19917c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
19927c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hcrx->ccid3hcrx_loss_interval_hist);
19937c657876SArnaldo Carvalho de Melo 
19947c657876SArnaldo Carvalho de Melo 	return 0;
19957c657876SArnaldo Carvalho de Melo }
19967c657876SArnaldo Carvalho de Melo 
19977c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_exit(struct sock *sk)
19987c657876SArnaldo Carvalho de Melo {
19997c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
20007c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
20017c657876SArnaldo Carvalho de Melo 
20027c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
20037c657876SArnaldo Carvalho de Melo 
20047c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
20057c657876SArnaldo Carvalho de Melo 		return;
20067c657876SArnaldo Carvalho de Melo 
20077c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
20087c657876SArnaldo Carvalho de Melo 
20097c657876SArnaldo Carvalho de Melo 	/* Empty packet history */
20108c60f3faSArnaldo Carvalho de Melo 	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
20117c657876SArnaldo Carvalho de Melo 
20127c657876SArnaldo Carvalho de Melo 	/* Empty loss interval history */
20137c657876SArnaldo Carvalho de Melo 	ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
20147c657876SArnaldo Carvalho de Melo 
20157c657876SArnaldo Carvalho de Melo 	kfree(dp->dccps_hc_rx_ccid_private);
20167c657876SArnaldo Carvalho de Melo 	dp->dccps_hc_rx_ccid_private = NULL;
20177c657876SArnaldo Carvalho de Melo }
20187c657876SArnaldo Carvalho de Melo 
20197c657876SArnaldo Carvalho de Melo static struct ccid ccid3 = {
20207c657876SArnaldo Carvalho de Melo 	.ccid_id		   = 3,
20217c657876SArnaldo Carvalho de Melo 	.ccid_name		   = "ccid3",
20227c657876SArnaldo Carvalho de Melo 	.ccid_owner		   = THIS_MODULE,
20237c657876SArnaldo Carvalho de Melo 	.ccid_init		   = ccid3_init,
20247c657876SArnaldo Carvalho de Melo 	.ccid_exit		   = ccid3_exit,
20257c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
20267c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,
20277c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_send_packet	   = ccid3_hc_tx_send_packet,
20287c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_packet_sent	   = ccid3_hc_tx_packet_sent,
20297c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_packet_recv	   = ccid3_hc_tx_packet_recv,
20307c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
20317c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_parse_options  = ccid3_hc_tx_parse_options,
20327c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_init	   = ccid3_hc_rx_init,
20337c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_exit	   = ccid3_hc_rx_exit,
20347c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
20357c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_packet_recv	   = ccid3_hc_rx_packet_recv,
20367c657876SArnaldo Carvalho de Melo };
20377c657876SArnaldo Carvalho de Melo 
20387c657876SArnaldo Carvalho de Melo module_param(ccid3_debug, int, 0444);
20397c657876SArnaldo Carvalho de Melo MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
20407c657876SArnaldo Carvalho de Melo 
20417c657876SArnaldo Carvalho de Melo static __init int ccid3_module_init(void)
20427c657876SArnaldo Carvalho de Melo {
20438c60f3faSArnaldo Carvalho de Melo 	int rc = -ENOBUFS;
20447c657876SArnaldo Carvalho de Melo 
20458c60f3faSArnaldo Carvalho de Melo 	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
20468c60f3faSArnaldo Carvalho de Melo 	if (ccid3_rx_hist == NULL)
20477c657876SArnaldo Carvalho de Melo 		goto out;
20487c657876SArnaldo Carvalho de Melo 
20498c60f3faSArnaldo Carvalho de Melo 	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
20508c60f3faSArnaldo Carvalho de Melo 	if (ccid3_tx_hist == NULL)
20518c60f3faSArnaldo Carvalho de Melo 		goto out_free_rx;
20527c657876SArnaldo Carvalho de Melo 
20538c60f3faSArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_slab = kmem_cache_create("li_hist_ccid3",
20548c60f3faSArnaldo Carvalho de Melo 				  sizeof(struct ccid3_loss_interval_hist_entry),
20558c60f3faSArnaldo Carvalho de Melo 							  0, SLAB_HWCACHE_ALIGN,
20568c60f3faSArnaldo Carvalho de Melo 							  NULL, NULL);
20577c657876SArnaldo Carvalho de Melo 	if (ccid3_loss_interval_hist_slab == NULL)
20588c60f3faSArnaldo Carvalho de Melo 		goto out_free_tx;
20597c657876SArnaldo Carvalho de Melo 
20607c657876SArnaldo Carvalho de Melo 	rc = ccid_register(&ccid3);
20617c657876SArnaldo Carvalho de Melo 	if (rc != 0)
20627c657876SArnaldo Carvalho de Melo 		goto out_free_loss_interval_history;
20637c657876SArnaldo Carvalho de Melo out:
20647c657876SArnaldo Carvalho de Melo 	return rc;
20658c60f3faSArnaldo Carvalho de Melo 
20667c657876SArnaldo Carvalho de Melo out_free_loss_interval_history:
20677c657876SArnaldo Carvalho de Melo 	kmem_cache_destroy(ccid3_loss_interval_hist_slab);
20687c657876SArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_slab = NULL;
20698c60f3faSArnaldo Carvalho de Melo out_free_tx:
20708c60f3faSArnaldo Carvalho de Melo 	dccp_tx_hist_delete(ccid3_tx_hist);
20718c60f3faSArnaldo Carvalho de Melo 	ccid3_tx_hist = NULL;
20728c60f3faSArnaldo Carvalho de Melo out_free_rx:
20738c60f3faSArnaldo Carvalho de Melo 	dccp_rx_hist_delete(ccid3_rx_hist);
20748c60f3faSArnaldo Carvalho de Melo 	ccid3_rx_hist = NULL;
20757c657876SArnaldo Carvalho de Melo 	goto out;
20767c657876SArnaldo Carvalho de Melo }
20777c657876SArnaldo Carvalho de Melo module_init(ccid3_module_init);
20787c657876SArnaldo Carvalho de Melo 
20797c657876SArnaldo Carvalho de Melo static __exit void ccid3_module_exit(void)
20807c657876SArnaldo Carvalho de Melo {
20817c657876SArnaldo Carvalho de Melo 	ccid_unregister(&ccid3);
20827c657876SArnaldo Carvalho de Melo 
20838c60f3faSArnaldo Carvalho de Melo 	if (ccid3_tx_hist != NULL) {
20848c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_delete(ccid3_tx_hist);
20858c60f3faSArnaldo Carvalho de Melo 		ccid3_tx_hist = NULL;
20867c657876SArnaldo Carvalho de Melo 	}
20878c60f3faSArnaldo Carvalho de Melo 	if (ccid3_rx_hist != NULL) {
20888c60f3faSArnaldo Carvalho de Melo 		dccp_rx_hist_delete(ccid3_rx_hist);
20898c60f3faSArnaldo Carvalho de Melo 		ccid3_rx_hist = NULL;
20907c657876SArnaldo Carvalho de Melo 	}
20917c657876SArnaldo Carvalho de Melo 	if (ccid3_loss_interval_hist_slab != NULL) {
20927c657876SArnaldo Carvalho de Melo 		kmem_cache_destroy(ccid3_loss_interval_hist_slab);
20937c657876SArnaldo Carvalho de Melo 		ccid3_loss_interval_hist_slab = NULL;
20947c657876SArnaldo Carvalho de Melo 	}
20957c657876SArnaldo Carvalho de Melo }
20967c657876SArnaldo Carvalho de Melo module_exit(ccid3_module_exit);
20977c657876SArnaldo Carvalho de Melo 
20987c657876SArnaldo Carvalho de Melo MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz> & Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
20997c657876SArnaldo Carvalho de Melo MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
21007c657876SArnaldo Carvalho de Melo MODULE_LICENSE("GPL");
21017c657876SArnaldo Carvalho de Melo MODULE_ALIAS("net-dccp-ccid-3");
2102