xref: /openbmc/linux/net/dccp/ccids/ccid3.c (revision 2babe1f6)
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.
51bc09869SIan McDonald  *  Copyright (c) 2005 Ian McDonald <iam4@cs.waikato.ac.nz>
67c657876SArnaldo Carvalho de Melo  *
77c657876SArnaldo Carvalho de Melo  *  An implementation of the DCCP protocol
87c657876SArnaldo Carvalho de Melo  *
97c657876SArnaldo Carvalho de Melo  *  This code has been developed by the University of Waikato WAND
107c657876SArnaldo Carvalho de Melo  *  research group. For further information please see http://www.wand.net.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 
85a1d3a355SArnaldo Carvalho de Melo static struct dccp_tx_hist *ccid3_tx_hist;
86a1d3a355SArnaldo Carvalho de Melo static 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 
90a1d3a355SArnaldo Carvalho de Melo static inline struct ccid3_loss_interval_hist_entry *
91a1d3a355SArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_entry_new(const unsigned int __nocast prio)
927c657876SArnaldo Carvalho de Melo {
937c657876SArnaldo Carvalho de Melo 	return kmem_cache_alloc(ccid3_loss_interval_hist_slab, prio);
947c657876SArnaldo Carvalho de Melo }
957c657876SArnaldo Carvalho de Melo 
967c657876SArnaldo Carvalho de Melo static inline void ccid3_loss_interval_hist_entry_delete(struct ccid3_loss_interval_hist_entry *entry)
977c657876SArnaldo Carvalho de Melo {
987c657876SArnaldo Carvalho de Melo 	if (entry != NULL)
997c657876SArnaldo Carvalho de Melo 		kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
1007c657876SArnaldo Carvalho de Melo }
1017c657876SArnaldo Carvalho de Melo 
1027c657876SArnaldo Carvalho de Melo static void ccid3_loss_interval_history_delete(struct list_head *hist)
1037c657876SArnaldo Carvalho de Melo {
1047c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *entry, *next;
1057c657876SArnaldo Carvalho de Melo 
1067c657876SArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, hist, ccid3lih_node) {
1077c657876SArnaldo Carvalho de Melo 		list_del_init(&entry->ccid3lih_node);
1087c657876SArnaldo Carvalho de Melo 		kmem_cache_free(ccid3_loss_interval_hist_slab, entry);
1097c657876SArnaldo Carvalho de Melo 	}
1107c657876SArnaldo Carvalho de Melo }
1117c657876SArnaldo Carvalho de Melo 
1127c657876SArnaldo Carvalho de Melo static int ccid3_init(struct sock *sk)
1137c657876SArnaldo Carvalho de Melo {
1147c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1157c657876SArnaldo Carvalho de Melo 	return 0;
1167c657876SArnaldo Carvalho de Melo }
1177c657876SArnaldo Carvalho de Melo 
1187c657876SArnaldo Carvalho de Melo static void ccid3_exit(struct sock *sk)
1197c657876SArnaldo Carvalho de Melo {
1207c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
1217c657876SArnaldo Carvalho de Melo }
1227c657876SArnaldo Carvalho de Melo 
1237c657876SArnaldo Carvalho de Melo /* TFRC sender states */
1247c657876SArnaldo Carvalho de Melo enum ccid3_hc_tx_states {
1257c657876SArnaldo Carvalho de Melo        	TFRC_SSTATE_NO_SENT = 1,
1267c657876SArnaldo Carvalho de Melo 	TFRC_SSTATE_NO_FBACK,
1277c657876SArnaldo Carvalho de Melo 	TFRC_SSTATE_FBACK,
1287c657876SArnaldo Carvalho de Melo 	TFRC_SSTATE_TERM,
1297c657876SArnaldo Carvalho de Melo };
1307c657876SArnaldo Carvalho de Melo 
1317c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG
1327c657876SArnaldo Carvalho de Melo static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
1337c657876SArnaldo Carvalho de Melo {
1347c657876SArnaldo Carvalho de Melo 	static char *ccid3_state_names[] = {
1357c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_NO_SENT]  = "NO_SENT",
1367c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
1377c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_FBACK]    = "FBACK",
1387c657876SArnaldo Carvalho de Melo 	[TFRC_SSTATE_TERM]     = "TERM",
1397c657876SArnaldo Carvalho de Melo 	};
1407c657876SArnaldo Carvalho de Melo 
1417c657876SArnaldo Carvalho de Melo 	return ccid3_state_names[state];
1427c657876SArnaldo Carvalho de Melo }
1437c657876SArnaldo Carvalho de Melo #endif
1447c657876SArnaldo Carvalho de Melo 
1457c657876SArnaldo Carvalho de Melo static inline void ccid3_hc_tx_set_state(struct sock *sk, enum ccid3_hc_tx_states state)
1467c657876SArnaldo Carvalho de Melo {
1477c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
1487c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1497c657876SArnaldo Carvalho de Melo 	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
1507c657876SArnaldo Carvalho de Melo 
1517c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
1527c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate), ccid3_tx_state_name(state));
1537c657876SArnaldo Carvalho de Melo 	WARN_ON(state == oldstate);
1547c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_state = state;
1557c657876SArnaldo Carvalho de Melo }
1567c657876SArnaldo Carvalho de Melo 
157cef07fd6SArnaldo Carvalho de Melo static void timeval_sub(struct timeval large, struct timeval small,
158cef07fd6SArnaldo Carvalho de Melo 			struct timeval *result)
159cef07fd6SArnaldo Carvalho de Melo {
1607c657876SArnaldo Carvalho de Melo 	result->tv_sec = large.tv_sec-small.tv_sec;
1617c657876SArnaldo Carvalho de Melo 	if (large.tv_usec < small.tv_usec) {
1627c657876SArnaldo Carvalho de Melo 		(result->tv_sec)--;
163cef07fd6SArnaldo Carvalho de Melo 		result->tv_usec = USEC_PER_SEC +
164cef07fd6SArnaldo Carvalho de Melo 				  large.tv_usec - small.tv_usec;
1657c657876SArnaldo Carvalho de Melo 	} else
1667c657876SArnaldo Carvalho de Melo 		result->tv_usec = large.tv_usec-small.tv_usec;
1677c657876SArnaldo Carvalho de Melo }
1687c657876SArnaldo Carvalho de Melo 
169cef07fd6SArnaldo Carvalho de Melo static inline void timeval_fix(struct timeval *tv)
170cef07fd6SArnaldo Carvalho de Melo {
171cef07fd6SArnaldo Carvalho de Melo 	if (tv->tv_usec >= USEC_PER_SEC) {
1727c657876SArnaldo Carvalho de Melo 		tv->tv_sec++;
173cef07fd6SArnaldo Carvalho de Melo 		tv->tv_usec -= USEC_PER_SEC;
1747c657876SArnaldo Carvalho de Melo 	}
1757c657876SArnaldo Carvalho de Melo }
1767c657876SArnaldo Carvalho de Melo 
1777c657876SArnaldo Carvalho de Melo #define CALCX_ARRSIZE 500
1787c657876SArnaldo Carvalho de Melo 
1797c657876SArnaldo Carvalho de Melo #define CALCX_SPLIT 50000
1807c657876SArnaldo Carvalho de Melo /* equivalent to 0.05 */
1817c657876SArnaldo Carvalho de Melo 
1827c657876SArnaldo Carvalho de Melo static const u32 calcx_lookup[CALCX_ARRSIZE][2] = {
1837c657876SArnaldo Carvalho de Melo 	{ 37172 , 8172 },
1847c657876SArnaldo Carvalho de Melo 	{ 53499 , 11567 },
1857c657876SArnaldo Carvalho de Melo 	{ 66664 , 14180 },
1867c657876SArnaldo Carvalho de Melo 	{ 78298 , 16388 },
1877c657876SArnaldo Carvalho de Melo 	{ 89021 , 18339 },
1887c657876SArnaldo Carvalho de Melo 	{ 99147 , 20108 },
1897c657876SArnaldo Carvalho de Melo 	{ 108858 , 21738 },
1907c657876SArnaldo Carvalho de Melo 	{ 118273 , 23260 },
1917c657876SArnaldo Carvalho de Melo 	{ 127474 , 24693 },
1927c657876SArnaldo Carvalho de Melo 	{ 136520 , 26052 },
1937c657876SArnaldo Carvalho de Melo 	{ 145456 , 27348 },
1947c657876SArnaldo Carvalho de Melo 	{ 154316 , 28589 },
1957c657876SArnaldo Carvalho de Melo 	{ 163130 , 29783 },
1967c657876SArnaldo Carvalho de Melo 	{ 171919 , 30935 },
1977c657876SArnaldo Carvalho de Melo 	{ 180704 , 32049 },
1987c657876SArnaldo Carvalho de Melo 	{ 189502 , 33130 },
1997c657876SArnaldo Carvalho de Melo 	{ 198328 , 34180 },
2007c657876SArnaldo Carvalho de Melo 	{ 207194 , 35202 },
2017c657876SArnaldo Carvalho de Melo 	{ 216114 , 36198 },
2027c657876SArnaldo Carvalho de Melo 	{ 225097 , 37172 },
2037c657876SArnaldo Carvalho de Melo 	{ 234153 , 38123 },
2047c657876SArnaldo Carvalho de Melo 	{ 243294 , 39055 },
2057c657876SArnaldo Carvalho de Melo 	{ 252527 , 39968 },
2067c657876SArnaldo Carvalho de Melo 	{ 261861 , 40864 },
2077c657876SArnaldo Carvalho de Melo 	{ 271305 , 41743 },
2087c657876SArnaldo Carvalho de Melo 	{ 280866 , 42607 },
2097c657876SArnaldo Carvalho de Melo 	{ 290553 , 43457 },
2107c657876SArnaldo Carvalho de Melo 	{ 300372 , 44293 },
2117c657876SArnaldo Carvalho de Melo 	{ 310333 , 45117 },
2127c657876SArnaldo Carvalho de Melo 	{ 320441 , 45929 },
2137c657876SArnaldo Carvalho de Melo 	{ 330705 , 46729 },
2147c657876SArnaldo Carvalho de Melo 	{ 341131 , 47518 },
2157c657876SArnaldo Carvalho de Melo 	{ 351728 , 48297 },
2167c657876SArnaldo Carvalho de Melo 	{ 362501 , 49066 },
2177c657876SArnaldo Carvalho de Melo 	{ 373460 , 49826 },
2187c657876SArnaldo Carvalho de Melo 	{ 384609 , 50577 },
2197c657876SArnaldo Carvalho de Melo 	{ 395958 , 51320 },
2207c657876SArnaldo Carvalho de Melo 	{ 407513 , 52054 },
2217c657876SArnaldo Carvalho de Melo 	{ 419281 , 52780 },
2227c657876SArnaldo Carvalho de Melo 	{ 431270 , 53499 },
2237c657876SArnaldo Carvalho de Melo 	{ 443487 , 54211 },
2247c657876SArnaldo Carvalho de Melo 	{ 455940 , 54916 },
2257c657876SArnaldo Carvalho de Melo 	{ 468635 , 55614 },
2267c657876SArnaldo Carvalho de Melo 	{ 481581 , 56306 },
2277c657876SArnaldo Carvalho de Melo 	{ 494785 , 56991 },
2287c657876SArnaldo Carvalho de Melo 	{ 508254 , 57671 },
2297c657876SArnaldo Carvalho de Melo 	{ 521996 , 58345 },
2307c657876SArnaldo Carvalho de Melo 	{ 536019 , 59014 },
2317c657876SArnaldo Carvalho de Melo 	{ 550331 , 59677 },
2327c657876SArnaldo Carvalho de Melo 	{ 564939 , 60335 },
2337c657876SArnaldo Carvalho de Melo 	{ 579851 , 60988 },
2347c657876SArnaldo Carvalho de Melo 	{ 595075 , 61636 },
2357c657876SArnaldo Carvalho de Melo 	{ 610619 , 62279 },
2367c657876SArnaldo Carvalho de Melo 	{ 626491 , 62918 },
2377c657876SArnaldo Carvalho de Melo 	{ 642700 , 63553 },
2387c657876SArnaldo Carvalho de Melo 	{ 659253 , 64183 },
2397c657876SArnaldo Carvalho de Melo 	{ 676158 , 64809 },
2407c657876SArnaldo Carvalho de Melo 	{ 693424 , 65431 },
2417c657876SArnaldo Carvalho de Melo 	{ 711060 , 66050 },
2427c657876SArnaldo Carvalho de Melo 	{ 729073 , 66664 },
2437c657876SArnaldo Carvalho de Melo 	{ 747472 , 67275 },
2447c657876SArnaldo Carvalho de Melo 	{ 766266 , 67882 },
2457c657876SArnaldo Carvalho de Melo 	{ 785464 , 68486 },
2467c657876SArnaldo Carvalho de Melo 	{ 805073 , 69087 },
2477c657876SArnaldo Carvalho de Melo 	{ 825103 , 69684 },
2487c657876SArnaldo Carvalho de Melo 	{ 845562 , 70278 },
2497c657876SArnaldo Carvalho de Melo 	{ 866460 , 70868 },
2507c657876SArnaldo Carvalho de Melo 	{ 887805 , 71456 },
2517c657876SArnaldo Carvalho de Melo 	{ 909606 , 72041 },
2527c657876SArnaldo Carvalho de Melo 	{ 931873 , 72623 },
2537c657876SArnaldo Carvalho de Melo 	{ 954614 , 73202 },
2547c657876SArnaldo Carvalho de Melo 	{ 977839 , 73778 },
2557c657876SArnaldo Carvalho de Melo 	{ 1001557 , 74352 },
2567c657876SArnaldo Carvalho de Melo 	{ 1025777 , 74923 },
2577c657876SArnaldo Carvalho de Melo 	{ 1050508 , 75492 },
2587c657876SArnaldo Carvalho de Melo 	{ 1075761 , 76058 },
2597c657876SArnaldo Carvalho de Melo 	{ 1101544 , 76621 },
2607c657876SArnaldo Carvalho de Melo 	{ 1127867 , 77183 },
2617c657876SArnaldo Carvalho de Melo 	{ 1154739 , 77741 },
2627c657876SArnaldo Carvalho de Melo 	{ 1182172 , 78298 },
2637c657876SArnaldo Carvalho de Melo 	{ 1210173 , 78852 },
2647c657876SArnaldo Carvalho de Melo 	{ 1238753 , 79405 },
2657c657876SArnaldo Carvalho de Melo 	{ 1267922 , 79955 },
2667c657876SArnaldo Carvalho de Melo 	{ 1297689 , 80503 },
2677c657876SArnaldo Carvalho de Melo 	{ 1328066 , 81049 },
2687c657876SArnaldo Carvalho de Melo 	{ 1359060 , 81593 },
2697c657876SArnaldo Carvalho de Melo 	{ 1390684 , 82135 },
2707c657876SArnaldo Carvalho de Melo 	{ 1422947 , 82675 },
2717c657876SArnaldo Carvalho de Melo 	{ 1455859 , 83213 },
2727c657876SArnaldo Carvalho de Melo 	{ 1489430 , 83750 },
2737c657876SArnaldo Carvalho de Melo 	{ 1523671 , 84284 },
2747c657876SArnaldo Carvalho de Melo 	{ 1558593 , 84817 },
2757c657876SArnaldo Carvalho de Melo 	{ 1594205 , 85348 },
2767c657876SArnaldo Carvalho de Melo 	{ 1630518 , 85878 },
2777c657876SArnaldo Carvalho de Melo 	{ 1667543 , 86406 },
2787c657876SArnaldo Carvalho de Melo 	{ 1705290 , 86932 },
2797c657876SArnaldo Carvalho de Melo 	{ 1743770 , 87457 },
2807c657876SArnaldo Carvalho de Melo 	{ 1782994 , 87980 },
2817c657876SArnaldo Carvalho de Melo 	{ 1822973 , 88501 },
2827c657876SArnaldo Carvalho de Melo 	{ 1863717 , 89021 },
2837c657876SArnaldo Carvalho de Melo 	{ 1905237 , 89540 },
2847c657876SArnaldo Carvalho de Melo 	{ 1947545 , 90057 },
2857c657876SArnaldo Carvalho de Melo 	{ 1990650 , 90573 },
2867c657876SArnaldo Carvalho de Melo 	{ 2034566 , 91087 },
2877c657876SArnaldo Carvalho de Melo 	{ 2079301 , 91600 },
2887c657876SArnaldo Carvalho de Melo 	{ 2124869 , 92111 },
2897c657876SArnaldo Carvalho de Melo 	{ 2171279 , 92622 },
2907c657876SArnaldo Carvalho de Melo 	{ 2218543 , 93131 },
2917c657876SArnaldo Carvalho de Melo 	{ 2266673 , 93639 },
2927c657876SArnaldo Carvalho de Melo 	{ 2315680 , 94145 },
2937c657876SArnaldo Carvalho de Melo 	{ 2365575 , 94650 },
2947c657876SArnaldo Carvalho de Melo 	{ 2416371 , 95154 },
2957c657876SArnaldo Carvalho de Melo 	{ 2468077 , 95657 },
2967c657876SArnaldo Carvalho de Melo 	{ 2520707 , 96159 },
2977c657876SArnaldo Carvalho de Melo 	{ 2574271 , 96660 },
2987c657876SArnaldo Carvalho de Melo 	{ 2628782 , 97159 },
2997c657876SArnaldo Carvalho de Melo 	{ 2684250 , 97658 },
3007c657876SArnaldo Carvalho de Melo 	{ 2740689 , 98155 },
3017c657876SArnaldo Carvalho de Melo 	{ 2798110 , 98651 },
3027c657876SArnaldo Carvalho de Melo 	{ 2856524 , 99147 },
3037c657876SArnaldo Carvalho de Melo 	{ 2915944 , 99641 },
3047c657876SArnaldo Carvalho de Melo 	{ 2976382 , 100134 },
3057c657876SArnaldo Carvalho de Melo 	{ 3037850 , 100626 },
3067c657876SArnaldo Carvalho de Melo 	{ 3100360 , 101117 },
3077c657876SArnaldo Carvalho de Melo 	{ 3163924 , 101608 },
3087c657876SArnaldo Carvalho de Melo 	{ 3228554 , 102097 },
3097c657876SArnaldo Carvalho de Melo 	{ 3294263 , 102586 },
3107c657876SArnaldo Carvalho de Melo 	{ 3361063 , 103073 },
3117c657876SArnaldo Carvalho de Melo 	{ 3428966 , 103560 },
3127c657876SArnaldo Carvalho de Melo 	{ 3497984 , 104045 },
3137c657876SArnaldo Carvalho de Melo 	{ 3568131 , 104530 },
3147c657876SArnaldo Carvalho de Melo 	{ 3639419 , 105014 },
3157c657876SArnaldo Carvalho de Melo 	{ 3711860 , 105498 },
3167c657876SArnaldo Carvalho de Melo 	{ 3785467 , 105980 },
3177c657876SArnaldo Carvalho de Melo 	{ 3860253 , 106462 },
3187c657876SArnaldo Carvalho de Melo 	{ 3936229 , 106942 },
3197c657876SArnaldo Carvalho de Melo 	{ 4013410 , 107422 },
3207c657876SArnaldo Carvalho de Melo 	{ 4091808 , 107902 },
3217c657876SArnaldo Carvalho de Melo 	{ 4171435 , 108380 },
3227c657876SArnaldo Carvalho de Melo 	{ 4252306 , 108858 },
3237c657876SArnaldo Carvalho de Melo 	{ 4334431 , 109335 },
3247c657876SArnaldo Carvalho de Melo 	{ 4417825 , 109811 },
3257c657876SArnaldo Carvalho de Melo 	{ 4502501 , 110287 },
3267c657876SArnaldo Carvalho de Melo 	{ 4588472 , 110762 },
3277c657876SArnaldo Carvalho de Melo 	{ 4675750 , 111236 },
3287c657876SArnaldo Carvalho de Melo 	{ 4764349 , 111709 },
3297c657876SArnaldo Carvalho de Melo 	{ 4854283 , 112182 },
3307c657876SArnaldo Carvalho de Melo 	{ 4945564 , 112654 },
3317c657876SArnaldo Carvalho de Melo 	{ 5038206 , 113126 },
3327c657876SArnaldo Carvalho de Melo 	{ 5132223 , 113597 },
3337c657876SArnaldo Carvalho de Melo 	{ 5227627 , 114067 },
3347c657876SArnaldo Carvalho de Melo 	{ 5324432 , 114537 },
3357c657876SArnaldo Carvalho de Melo 	{ 5422652 , 115006 },
3367c657876SArnaldo Carvalho de Melo 	{ 5522299 , 115474 },
3377c657876SArnaldo Carvalho de Melo 	{ 5623389 , 115942 },
3387c657876SArnaldo Carvalho de Melo 	{ 5725934 , 116409 },
3397c657876SArnaldo Carvalho de Melo 	{ 5829948 , 116876 },
3407c657876SArnaldo Carvalho de Melo 	{ 5935446 , 117342 },
3417c657876SArnaldo Carvalho de Melo 	{ 6042439 , 117808 },
3427c657876SArnaldo Carvalho de Melo 	{ 6150943 , 118273 },
3437c657876SArnaldo Carvalho de Melo 	{ 6260972 , 118738 },
3447c657876SArnaldo Carvalho de Melo 	{ 6372538 , 119202 },
3457c657876SArnaldo Carvalho de Melo 	{ 6485657 , 119665 },
3467c657876SArnaldo Carvalho de Melo 	{ 6600342 , 120128 },
3477c657876SArnaldo Carvalho de Melo 	{ 6716607 , 120591 },
3487c657876SArnaldo Carvalho de Melo 	{ 6834467 , 121053 },
3497c657876SArnaldo Carvalho de Melo 	{ 6953935 , 121514 },
3507c657876SArnaldo Carvalho de Melo 	{ 7075025 , 121976 },
3517c657876SArnaldo Carvalho de Melo 	{ 7197752 , 122436 },
3527c657876SArnaldo Carvalho de Melo 	{ 7322131 , 122896 },
3537c657876SArnaldo Carvalho de Melo 	{ 7448175 , 123356 },
3547c657876SArnaldo Carvalho de Melo 	{ 7575898 , 123815 },
3557c657876SArnaldo Carvalho de Melo 	{ 7705316 , 124274 },
3567c657876SArnaldo Carvalho de Melo 	{ 7836442 , 124733 },
3577c657876SArnaldo Carvalho de Melo 	{ 7969291 , 125191 },
3587c657876SArnaldo Carvalho de Melo 	{ 8103877 , 125648 },
3597c657876SArnaldo Carvalho de Melo 	{ 8240216 , 126105 },
3607c657876SArnaldo Carvalho de Melo 	{ 8378321 , 126562 },
3617c657876SArnaldo Carvalho de Melo 	{ 8518208 , 127018 },
3627c657876SArnaldo Carvalho de Melo 	{ 8659890 , 127474 },
3637c657876SArnaldo Carvalho de Melo 	{ 8803384 , 127930 },
3647c657876SArnaldo Carvalho de Melo 	{ 8948702 , 128385 },
3657c657876SArnaldo Carvalho de Melo 	{ 9095861 , 128840 },
3667c657876SArnaldo Carvalho de Melo 	{ 9244875 , 129294 },
3677c657876SArnaldo Carvalho de Melo 	{ 9395760 , 129748 },
3687c657876SArnaldo Carvalho de Melo 	{ 9548529 , 130202 },
3697c657876SArnaldo Carvalho de Melo 	{ 9703198 , 130655 },
3707c657876SArnaldo Carvalho de Melo 	{ 9859782 , 131108 },
3717c657876SArnaldo Carvalho de Melo 	{ 10018296 , 131561 },
3727c657876SArnaldo Carvalho de Melo 	{ 10178755 , 132014 },
3737c657876SArnaldo Carvalho de Melo 	{ 10341174 , 132466 },
3747c657876SArnaldo Carvalho de Melo 	{ 10505569 , 132917 },
3757c657876SArnaldo Carvalho de Melo 	{ 10671954 , 133369 },
3767c657876SArnaldo Carvalho de Melo 	{ 10840345 , 133820 },
3777c657876SArnaldo Carvalho de Melo 	{ 11010757 , 134271 },
3787c657876SArnaldo Carvalho de Melo 	{ 11183206 , 134721 },
3797c657876SArnaldo Carvalho de Melo 	{ 11357706 , 135171 },
3807c657876SArnaldo Carvalho de Melo 	{ 11534274 , 135621 },
3817c657876SArnaldo Carvalho de Melo 	{ 11712924 , 136071 },
3827c657876SArnaldo Carvalho de Melo 	{ 11893673 , 136520 },
3837c657876SArnaldo Carvalho de Melo 	{ 12076536 , 136969 },
3847c657876SArnaldo Carvalho de Melo 	{ 12261527 , 137418 },
3857c657876SArnaldo Carvalho de Melo 	{ 12448664 , 137867 },
3867c657876SArnaldo Carvalho de Melo 	{ 12637961 , 138315 },
3877c657876SArnaldo Carvalho de Melo 	{ 12829435 , 138763 },
3887c657876SArnaldo Carvalho de Melo 	{ 13023101 , 139211 },
3897c657876SArnaldo Carvalho de Melo 	{ 13218974 , 139658 },
3907c657876SArnaldo Carvalho de Melo 	{ 13417071 , 140106 },
3917c657876SArnaldo Carvalho de Melo 	{ 13617407 , 140553 },
3927c657876SArnaldo Carvalho de Melo 	{ 13819999 , 140999 },
3937c657876SArnaldo Carvalho de Melo 	{ 14024862 , 141446 },
3947c657876SArnaldo Carvalho de Melo 	{ 14232012 , 141892 },
3957c657876SArnaldo Carvalho de Melo 	{ 14441465 , 142339 },
3967c657876SArnaldo Carvalho de Melo 	{ 14653238 , 142785 },
3977c657876SArnaldo Carvalho de Melo 	{ 14867346 , 143230 },
3987c657876SArnaldo Carvalho de Melo 	{ 15083805 , 143676 },
3997c657876SArnaldo Carvalho de Melo 	{ 15302632 , 144121 },
4007c657876SArnaldo Carvalho de Melo 	{ 15523842 , 144566 },
4017c657876SArnaldo Carvalho de Melo 	{ 15747453 , 145011 },
4027c657876SArnaldo Carvalho de Melo 	{ 15973479 , 145456 },
4037c657876SArnaldo Carvalho de Melo 	{ 16201939 , 145900 },
4047c657876SArnaldo Carvalho de Melo 	{ 16432847 , 146345 },
4057c657876SArnaldo Carvalho de Melo 	{ 16666221 , 146789 },
4067c657876SArnaldo Carvalho de Melo 	{ 16902076 , 147233 },
4077c657876SArnaldo Carvalho de Melo 	{ 17140429 , 147677 },
4087c657876SArnaldo Carvalho de Melo 	{ 17381297 , 148121 },
4097c657876SArnaldo Carvalho de Melo 	{ 17624696 , 148564 },
4107c657876SArnaldo Carvalho de Melo 	{ 17870643 , 149007 },
4117c657876SArnaldo Carvalho de Melo 	{ 18119154 , 149451 },
4127c657876SArnaldo Carvalho de Melo 	{ 18370247 , 149894 },
4137c657876SArnaldo Carvalho de Melo 	{ 18623936 , 150336 },
4147c657876SArnaldo Carvalho de Melo 	{ 18880241 , 150779 },
4157c657876SArnaldo Carvalho de Melo 	{ 19139176 , 151222 },
4167c657876SArnaldo Carvalho de Melo 	{ 19400759 , 151664 },
4177c657876SArnaldo Carvalho de Melo 	{ 19665007 , 152107 },
4187c657876SArnaldo Carvalho de Melo 	{ 19931936 , 152549 },
4197c657876SArnaldo Carvalho de Melo 	{ 20201564 , 152991 },
4207c657876SArnaldo Carvalho de Melo 	{ 20473907 , 153433 },
4217c657876SArnaldo Carvalho de Melo 	{ 20748982 , 153875 },
4227c657876SArnaldo Carvalho de Melo 	{ 21026807 , 154316 },
4237c657876SArnaldo Carvalho de Melo 	{ 21307399 , 154758 },
4247c657876SArnaldo Carvalho de Melo 	{ 21590773 , 155199 },
4257c657876SArnaldo Carvalho de Melo 	{ 21876949 , 155641 },
4267c657876SArnaldo Carvalho de Melo 	{ 22165941 , 156082 },
4277c657876SArnaldo Carvalho de Melo 	{ 22457769 , 156523 },
4287c657876SArnaldo Carvalho de Melo 	{ 22752449 , 156964 },
4297c657876SArnaldo Carvalho de Melo 	{ 23049999 , 157405 },
4307c657876SArnaldo Carvalho de Melo 	{ 23350435 , 157846 },
4317c657876SArnaldo Carvalho de Melo 	{ 23653774 , 158287 },
4327c657876SArnaldo Carvalho de Melo 	{ 23960036 , 158727 },
4337c657876SArnaldo Carvalho de Melo 	{ 24269236 , 159168 },
4347c657876SArnaldo Carvalho de Melo 	{ 24581392 , 159608 },
4357c657876SArnaldo Carvalho de Melo 	{ 24896521 , 160049 },
4367c657876SArnaldo Carvalho de Melo 	{ 25214642 , 160489 },
4377c657876SArnaldo Carvalho de Melo 	{ 25535772 , 160929 },
4387c657876SArnaldo Carvalho de Melo 	{ 25859927 , 161370 },
4397c657876SArnaldo Carvalho de Melo 	{ 26187127 , 161810 },
4407c657876SArnaldo Carvalho de Melo 	{ 26517388 , 162250 },
4417c657876SArnaldo Carvalho de Melo 	{ 26850728 , 162690 },
4427c657876SArnaldo Carvalho de Melo 	{ 27187165 , 163130 },
4437c657876SArnaldo Carvalho de Melo 	{ 27526716 , 163569 },
4447c657876SArnaldo Carvalho de Melo 	{ 27869400 , 164009 },
4457c657876SArnaldo Carvalho de Melo 	{ 28215234 , 164449 },
4467c657876SArnaldo Carvalho de Melo 	{ 28564236 , 164889 },
4477c657876SArnaldo Carvalho de Melo 	{ 28916423 , 165328 },
4487c657876SArnaldo Carvalho de Melo 	{ 29271815 , 165768 },
4497c657876SArnaldo Carvalho de Melo 	{ 29630428 , 166208 },
4507c657876SArnaldo Carvalho de Melo 	{ 29992281 , 166647 },
4517c657876SArnaldo Carvalho de Melo 	{ 30357392 , 167087 },
4527c657876SArnaldo Carvalho de Melo 	{ 30725779 , 167526 },
4537c657876SArnaldo Carvalho de Melo 	{ 31097459 , 167965 },
4547c657876SArnaldo Carvalho de Melo 	{ 31472452 , 168405 },
4557c657876SArnaldo Carvalho de Melo 	{ 31850774 , 168844 },
4567c657876SArnaldo Carvalho de Melo 	{ 32232445 , 169283 },
4577c657876SArnaldo Carvalho de Melo 	{ 32617482 , 169723 },
4587c657876SArnaldo Carvalho de Melo 	{ 33005904 , 170162 },
4597c657876SArnaldo Carvalho de Melo 	{ 33397730 , 170601 },
4607c657876SArnaldo Carvalho de Melo 	{ 33792976 , 171041 },
4617c657876SArnaldo Carvalho de Melo 	{ 34191663 , 171480 },
4627c657876SArnaldo Carvalho de Melo 	{ 34593807 , 171919 },
4637c657876SArnaldo Carvalho de Melo 	{ 34999428 , 172358 },
4647c657876SArnaldo Carvalho de Melo 	{ 35408544 , 172797 },
4657c657876SArnaldo Carvalho de Melo 	{ 35821174 , 173237 },
4667c657876SArnaldo Carvalho de Melo 	{ 36237335 , 173676 },
4677c657876SArnaldo Carvalho de Melo 	{ 36657047 , 174115 },
4687c657876SArnaldo Carvalho de Melo 	{ 37080329 , 174554 },
4697c657876SArnaldo Carvalho de Melo 	{ 37507197 , 174993 },
4707c657876SArnaldo Carvalho de Melo 	{ 37937673 , 175433 },
4717c657876SArnaldo Carvalho de Melo 	{ 38371773 , 175872 },
4727c657876SArnaldo Carvalho de Melo 	{ 38809517 , 176311 },
4737c657876SArnaldo Carvalho de Melo 	{ 39250924 , 176750 },
4747c657876SArnaldo Carvalho de Melo 	{ 39696012 , 177190 },
4757c657876SArnaldo Carvalho de Melo 	{ 40144800 , 177629 },
4767c657876SArnaldo Carvalho de Melo 	{ 40597308 , 178068 },
4777c657876SArnaldo Carvalho de Melo 	{ 41053553 , 178507 },
4787c657876SArnaldo Carvalho de Melo 	{ 41513554 , 178947 },
4797c657876SArnaldo Carvalho de Melo 	{ 41977332 , 179386 },
4807c657876SArnaldo Carvalho de Melo 	{ 42444904 , 179825 },
4817c657876SArnaldo Carvalho de Melo 	{ 42916290 , 180265 },
4827c657876SArnaldo Carvalho de Melo 	{ 43391509 , 180704 },
4837c657876SArnaldo Carvalho de Melo 	{ 43870579 , 181144 },
4847c657876SArnaldo Carvalho de Melo 	{ 44353520 , 181583 },
4857c657876SArnaldo Carvalho de Melo 	{ 44840352 , 182023 },
4867c657876SArnaldo Carvalho de Melo 	{ 45331092 , 182462 },
4877c657876SArnaldo Carvalho de Melo 	{ 45825761 , 182902 },
4887c657876SArnaldo Carvalho de Melo 	{ 46324378 , 183342 },
4897c657876SArnaldo Carvalho de Melo 	{ 46826961 , 183781 },
4907c657876SArnaldo Carvalho de Melo 	{ 47333531 , 184221 },
4917c657876SArnaldo Carvalho de Melo 	{ 47844106 , 184661 },
4927c657876SArnaldo Carvalho de Melo 	{ 48358706 , 185101 },
4937c657876SArnaldo Carvalho de Melo 	{ 48877350 , 185541 },
4947c657876SArnaldo Carvalho de Melo 	{ 49400058 , 185981 },
4957c657876SArnaldo Carvalho de Melo 	{ 49926849 , 186421 },
4967c657876SArnaldo Carvalho de Melo 	{ 50457743 , 186861 },
4977c657876SArnaldo Carvalho de Melo 	{ 50992759 , 187301 },
4987c657876SArnaldo Carvalho de Melo 	{ 51531916 , 187741 },
4997c657876SArnaldo Carvalho de Melo 	{ 52075235 , 188181 },
5007c657876SArnaldo Carvalho de Melo 	{ 52622735 , 188622 },
5017c657876SArnaldo Carvalho de Melo 	{ 53174435 , 189062 },
5027c657876SArnaldo Carvalho de Melo 	{ 53730355 , 189502 },
5037c657876SArnaldo Carvalho de Melo 	{ 54290515 , 189943 },
5047c657876SArnaldo Carvalho de Melo 	{ 54854935 , 190383 },
5057c657876SArnaldo Carvalho de Melo 	{ 55423634 , 190824 },
5067c657876SArnaldo Carvalho de Melo 	{ 55996633 , 191265 },
5077c657876SArnaldo Carvalho de Melo 	{ 56573950 , 191706 },
5087c657876SArnaldo Carvalho de Melo 	{ 57155606 , 192146 },
5097c657876SArnaldo Carvalho de Melo 	{ 57741621 , 192587 },
5107c657876SArnaldo Carvalho de Melo 	{ 58332014 , 193028 },
5117c657876SArnaldo Carvalho de Melo 	{ 58926806 , 193470 },
5127c657876SArnaldo Carvalho de Melo 	{ 59526017 , 193911 },
5137c657876SArnaldo Carvalho de Melo 	{ 60129666 , 194352 },
5147c657876SArnaldo Carvalho de Melo 	{ 60737774 , 194793 },
5157c657876SArnaldo Carvalho de Melo 	{ 61350361 , 195235 },
5167c657876SArnaldo Carvalho de Melo 	{ 61967446 , 195677 },
5177c657876SArnaldo Carvalho de Melo 	{ 62589050 , 196118 },
5187c657876SArnaldo Carvalho de Melo 	{ 63215194 , 196560 },
5197c657876SArnaldo Carvalho de Melo 	{ 63845897 , 197002 },
5207c657876SArnaldo Carvalho de Melo 	{ 64481179 , 197444 },
5217c657876SArnaldo Carvalho de Melo 	{ 65121061 , 197886 },
5227c657876SArnaldo Carvalho de Melo 	{ 65765563 , 198328 },
5237c657876SArnaldo Carvalho de Melo 	{ 66414705 , 198770 },
5247c657876SArnaldo Carvalho de Melo 	{ 67068508 , 199213 },
5257c657876SArnaldo Carvalho de Melo 	{ 67726992 , 199655 },
5267c657876SArnaldo Carvalho de Melo 	{ 68390177 , 200098 },
5277c657876SArnaldo Carvalho de Melo 	{ 69058085 , 200540 },
5287c657876SArnaldo Carvalho de Melo 	{ 69730735 , 200983 },
5297c657876SArnaldo Carvalho de Melo 	{ 70408147 , 201426 },
5307c657876SArnaldo Carvalho de Melo 	{ 71090343 , 201869 },
5317c657876SArnaldo Carvalho de Melo 	{ 71777343 , 202312 },
5327c657876SArnaldo Carvalho de Melo 	{ 72469168 , 202755 },
5337c657876SArnaldo Carvalho de Melo 	{ 73165837 , 203199 },
5347c657876SArnaldo Carvalho de Melo 	{ 73867373 , 203642 },
5357c657876SArnaldo Carvalho de Melo 	{ 74573795 , 204086 },
5367c657876SArnaldo Carvalho de Melo 	{ 75285124 , 204529 },
5377c657876SArnaldo Carvalho de Melo 	{ 76001380 , 204973 },
5387c657876SArnaldo Carvalho de Melo 	{ 76722586 , 205417 },
5397c657876SArnaldo Carvalho de Melo 	{ 77448761 , 205861 },
5407c657876SArnaldo Carvalho de Melo 	{ 78179926 , 206306 },
5417c657876SArnaldo Carvalho de Melo 	{ 78916102 , 206750 },
5427c657876SArnaldo Carvalho de Melo 	{ 79657310 , 207194 },
5437c657876SArnaldo Carvalho de Melo 	{ 80403571 , 207639 },
5447c657876SArnaldo Carvalho de Melo 	{ 81154906 , 208084 },
5457c657876SArnaldo Carvalho de Melo 	{ 81911335 , 208529 },
5467c657876SArnaldo Carvalho de Melo 	{ 82672880 , 208974 },
5477c657876SArnaldo Carvalho de Melo 	{ 83439562 , 209419 },
5487c657876SArnaldo Carvalho de Melo 	{ 84211402 , 209864 },
5497c657876SArnaldo Carvalho de Melo 	{ 84988421 , 210309 },
5507c657876SArnaldo Carvalho de Melo 	{ 85770640 , 210755 },
5517c657876SArnaldo Carvalho de Melo 	{ 86558080 , 211201 },
5527c657876SArnaldo Carvalho de Melo 	{ 87350762 , 211647 },
5537c657876SArnaldo Carvalho de Melo 	{ 88148708 , 212093 },
5547c657876SArnaldo Carvalho de Melo 	{ 88951938 , 212539 },
5557c657876SArnaldo Carvalho de Melo 	{ 89760475 , 212985 },
5567c657876SArnaldo Carvalho de Melo 	{ 90574339 , 213432 },
5577c657876SArnaldo Carvalho de Melo 	{ 91393551 , 213878 },
5587c657876SArnaldo Carvalho de Melo 	{ 92218133 , 214325 },
5597c657876SArnaldo Carvalho de Melo 	{ 93048107 , 214772 },
5607c657876SArnaldo Carvalho de Melo 	{ 93883493 , 215219 },
5617c657876SArnaldo Carvalho de Melo 	{ 94724314 , 215666 },
5627c657876SArnaldo Carvalho de Melo 	{ 95570590 , 216114 },
5637c657876SArnaldo Carvalho de Melo 	{ 96422343 , 216561 },
5647c657876SArnaldo Carvalho de Melo 	{ 97279594 , 217009 },
5657c657876SArnaldo Carvalho de Melo 	{ 98142366 , 217457 },
5667c657876SArnaldo Carvalho de Melo 	{ 99010679 , 217905 },
5677c657876SArnaldo Carvalho de Melo 	{ 99884556 , 218353 },
5687c657876SArnaldo Carvalho de Melo 	{ 100764018 , 218801 },
5697c657876SArnaldo Carvalho de Melo 	{ 101649086 , 219250 },
5707c657876SArnaldo Carvalho de Melo 	{ 102539782 , 219698 },
5717c657876SArnaldo Carvalho de Melo 	{ 103436128 , 220147 },
5727c657876SArnaldo Carvalho de Melo 	{ 104338146 , 220596 },
5737c657876SArnaldo Carvalho de Melo 	{ 105245857 , 221046 },
5747c657876SArnaldo Carvalho de Melo 	{ 106159284 , 221495 },
5757c657876SArnaldo Carvalho de Melo 	{ 107078448 , 221945 },
5767c657876SArnaldo Carvalho de Melo 	{ 108003370 , 222394 },
5777c657876SArnaldo Carvalho de Melo 	{ 108934074 , 222844 },
5787c657876SArnaldo Carvalho de Melo 	{ 109870580 , 223294 },
5797c657876SArnaldo Carvalho de Melo 	{ 110812910 , 223745 },
5807c657876SArnaldo Carvalho de Melo 	{ 111761087 , 224195 },
5817c657876SArnaldo Carvalho de Melo 	{ 112715133 , 224646 },
5827c657876SArnaldo Carvalho de Melo 	{ 113675069 , 225097 },
5837c657876SArnaldo Carvalho de Melo 	{ 114640918 , 225548 },
5847c657876SArnaldo Carvalho de Melo 	{ 115612702 , 225999 },
5857c657876SArnaldo Carvalho de Melo 	{ 116590442 , 226450 },
5867c657876SArnaldo Carvalho de Melo 	{ 117574162 , 226902 },
5877c657876SArnaldo Carvalho de Melo 	{ 118563882 , 227353 },
5887c657876SArnaldo Carvalho de Melo 	{ 119559626 , 227805 },
5897c657876SArnaldo Carvalho de Melo 	{ 120561415 , 228258 },
5907c657876SArnaldo Carvalho de Melo 	{ 121569272 , 228710 },
5917c657876SArnaldo Carvalho de Melo 	{ 122583219 , 229162 },
5927c657876SArnaldo Carvalho de Melo 	{ 123603278 , 229615 },
5937c657876SArnaldo Carvalho de Melo 	{ 124629471 , 230068 },
5947c657876SArnaldo Carvalho de Melo 	{ 125661822 , 230521 },
5957c657876SArnaldo Carvalho de Melo 	{ 126700352 , 230974 },
5967c657876SArnaldo Carvalho de Melo 	{ 127745083 , 231428 },
5977c657876SArnaldo Carvalho de Melo 	{ 128796039 , 231882 },
5987c657876SArnaldo Carvalho de Melo 	{ 129853241 , 232336 },
5997c657876SArnaldo Carvalho de Melo 	{ 130916713 , 232790 },
6007c657876SArnaldo Carvalho de Melo 	{ 131986475 , 233244 },
6017c657876SArnaldo Carvalho de Melo 	{ 133062553 , 233699 },
6027c657876SArnaldo Carvalho de Melo 	{ 134144966 , 234153 },
6037c657876SArnaldo Carvalho de Melo 	{ 135233739 , 234608 },
6047c657876SArnaldo Carvalho de Melo 	{ 136328894 , 235064 },
6057c657876SArnaldo Carvalho de Melo 	{ 137430453 , 235519 },
6067c657876SArnaldo Carvalho de Melo 	{ 138538440 , 235975 },
6077c657876SArnaldo Carvalho de Melo 	{ 139652876 , 236430 },
6087c657876SArnaldo Carvalho de Melo 	{ 140773786 , 236886 },
6097c657876SArnaldo Carvalho de Melo 	{ 141901190 , 237343 },
6107c657876SArnaldo Carvalho de Melo 	{ 143035113 , 237799 },
6117c657876SArnaldo Carvalho de Melo 	{ 144175576 , 238256 },
6127c657876SArnaldo Carvalho de Melo 	{ 145322604 , 238713 },
6137c657876SArnaldo Carvalho de Melo 	{ 146476218 , 239170 },
6147c657876SArnaldo Carvalho de Melo 	{ 147636442 , 239627 },
6157c657876SArnaldo Carvalho de Melo 	{ 148803298 , 240085 },
6167c657876SArnaldo Carvalho de Melo 	{ 149976809 , 240542 },
6177c657876SArnaldo Carvalho de Melo 	{ 151156999 , 241000 },
6187c657876SArnaldo Carvalho de Melo 	{ 152343890 , 241459 },
6197c657876SArnaldo Carvalho de Melo 	{ 153537506 , 241917 },
6207c657876SArnaldo Carvalho de Melo 	{ 154737869 , 242376 },
6217c657876SArnaldo Carvalho de Melo 	{ 155945002 , 242835 },
6227c657876SArnaldo Carvalho de Melo 	{ 157158929 , 243294 },
6237c657876SArnaldo Carvalho de Melo 	{ 158379673 , 243753 },
6247c657876SArnaldo Carvalho de Melo 	{ 159607257 , 244213 },
6257c657876SArnaldo Carvalho de Melo 	{ 160841704 , 244673 },
6267c657876SArnaldo Carvalho de Melo 	{ 162083037 , 245133 },
6277c657876SArnaldo Carvalho de Melo 	{ 163331279 , 245593 },
6287c657876SArnaldo Carvalho de Melo 	{ 164586455 , 246054 },
6297c657876SArnaldo Carvalho de Melo 	{ 165848586 , 246514 },
6307c657876SArnaldo Carvalho de Melo 	{ 167117696 , 246975 },
6317c657876SArnaldo Carvalho de Melo 	{ 168393810 , 247437 },
6327c657876SArnaldo Carvalho de Melo 	{ 169676949 , 247898 },
6337c657876SArnaldo Carvalho de Melo 	{ 170967138 , 248360 },
6347c657876SArnaldo Carvalho de Melo 	{ 172264399 , 248822 },
6357c657876SArnaldo Carvalho de Melo 	{ 173568757 , 249284 },
6367c657876SArnaldo Carvalho de Melo 	{ 174880235 , 249747 },
6377c657876SArnaldo Carvalho de Melo 	{ 176198856 , 250209 },
6387c657876SArnaldo Carvalho de Melo 	{ 177524643 , 250672 },
6397c657876SArnaldo Carvalho de Melo 	{ 178857621 , 251136 },
6407c657876SArnaldo Carvalho de Melo 	{ 180197813 , 251599 },
6417c657876SArnaldo Carvalho de Melo 	{ 181545242 , 252063 },
6427c657876SArnaldo Carvalho de Melo 	{ 182899933 , 252527 },
6437c657876SArnaldo Carvalho de Melo 	{ 184261908 , 252991 },
6447c657876SArnaldo Carvalho de Melo 	{ 185631191 , 253456 },
6457c657876SArnaldo Carvalho de Melo 	{ 187007807 , 253920 },
6467c657876SArnaldo Carvalho de Melo 	{ 188391778 , 254385 },
6477c657876SArnaldo Carvalho de Melo 	{ 189783129 , 254851 },
6487c657876SArnaldo Carvalho de Melo 	{ 191181884 , 255316 },
6497c657876SArnaldo Carvalho de Melo 	{ 192588065 , 255782 },
6507c657876SArnaldo Carvalho de Melo 	{ 194001698 , 256248 },
6517c657876SArnaldo Carvalho de Melo 	{ 195422805 , 256714 },
6527c657876SArnaldo Carvalho de Melo 	{ 196851411 , 257181 },
6537c657876SArnaldo Carvalho de Melo 	{ 198287540 , 257648 },
6547c657876SArnaldo Carvalho de Melo 	{ 199731215 , 258115 },
6557c657876SArnaldo Carvalho de Melo 	{ 201182461 , 258582 },
6567c657876SArnaldo Carvalho de Melo 	{ 202641302 , 259050 },
6577c657876SArnaldo Carvalho de Melo 	{ 204107760 , 259518 },
6587c657876SArnaldo Carvalho de Melo 	{ 205581862 , 259986 },
6597c657876SArnaldo Carvalho de Melo 	{ 207063630 , 260454 },
6607c657876SArnaldo Carvalho de Melo 	{ 208553088 , 260923 },
6617c657876SArnaldo Carvalho de Melo 	{ 210050262 , 261392 },
6627c657876SArnaldo Carvalho de Melo 	{ 211555174 , 261861 },
6637c657876SArnaldo Carvalho de Melo 	{ 213067849 , 262331 },
6647c657876SArnaldo Carvalho de Melo 	{ 214588312 , 262800 },
6657c657876SArnaldo Carvalho de Melo 	{ 216116586 , 263270 },
6667c657876SArnaldo Carvalho de Melo 	{ 217652696 , 263741 },
6677c657876SArnaldo Carvalho de Melo 	{ 219196666 , 264211 },
6687c657876SArnaldo Carvalho de Melo 	{ 220748520 , 264682 },
6697c657876SArnaldo Carvalho de Melo 	{ 222308282 , 265153 },
6707c657876SArnaldo Carvalho de Melo 	{ 223875978 , 265625 },
6717c657876SArnaldo Carvalho de Melo 	{ 225451630 , 266097 },
6727c657876SArnaldo Carvalho de Melo 	{ 227035265 , 266569 },
6737c657876SArnaldo Carvalho de Melo 	{ 228626905 , 267041 },
6747c657876SArnaldo Carvalho de Melo 	{ 230226576 , 267514 },
6757c657876SArnaldo Carvalho de Melo 	{ 231834302 , 267986 },
6767c657876SArnaldo Carvalho de Melo 	{ 233450107 , 268460 },
6777c657876SArnaldo Carvalho de Melo 	{ 235074016 , 268933 },
6787c657876SArnaldo Carvalho de Melo 	{ 236706054 , 269407 },
6797c657876SArnaldo Carvalho de Melo 	{ 238346244 , 269881 },
6807c657876SArnaldo Carvalho de Melo 	{ 239994613 , 270355 },
6817c657876SArnaldo Carvalho de Melo 	{ 241651183 , 270830 },
6827c657876SArnaldo Carvalho de Melo 	{ 243315981 , 271305 }
6837c657876SArnaldo Carvalho de Melo };
6847c657876SArnaldo Carvalho de Melo 
6857c657876SArnaldo Carvalho de Melo /* Calculate the send rate as per section 3.1 of RFC3448
6867c657876SArnaldo Carvalho de Melo 
6877c657876SArnaldo Carvalho de Melo Returns send rate in bytes per second
6887c657876SArnaldo Carvalho de Melo 
6897c657876SArnaldo Carvalho de Melo Integer maths and lookups are used as not allowed floating point in kernel
6907c657876SArnaldo Carvalho de Melo 
6917c657876SArnaldo Carvalho de Melo The function for Xcalc as per section 3.1 of RFC3448 is:
6927c657876SArnaldo Carvalho de Melo 
6937c657876SArnaldo Carvalho de Melo X =                            s
6947c657876SArnaldo Carvalho de Melo      -------------------------------------------------------------
6957c657876SArnaldo Carvalho de Melo      R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2)))
6967c657876SArnaldo Carvalho de Melo 
6977c657876SArnaldo Carvalho de Melo where
6987c657876SArnaldo Carvalho de Melo X is the trasmit rate in bytes/second
6997c657876SArnaldo Carvalho de Melo s is the packet size in bytes
7007c657876SArnaldo Carvalho de Melo R is the round trip time in seconds
7017c657876SArnaldo Carvalho de Melo p is the loss event rate, between 0 and 1.0, of the number of loss events
7027c657876SArnaldo Carvalho de Melo   as a fraction of the number of packets transmitted
7037c657876SArnaldo Carvalho de Melo t_RTO is the TCP retransmission timeout value in seconds
7047c657876SArnaldo Carvalho de Melo b is the number of packets acknowledged by a single TCP acknowledgement
7057c657876SArnaldo Carvalho de Melo 
7067c657876SArnaldo Carvalho de Melo we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
7077c657876SArnaldo Carvalho de Melo 
7087c657876SArnaldo Carvalho de Melo X =                            s
7097c657876SArnaldo Carvalho de Melo      -----------------------------------------------------------------------
7107c657876SArnaldo Carvalho de Melo      R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
7117c657876SArnaldo Carvalho de Melo 
7127c657876SArnaldo Carvalho de Melo 
7137c657876SArnaldo Carvalho de Melo which we can break down into:
7147c657876SArnaldo Carvalho de Melo 
7157c657876SArnaldo Carvalho de Melo X =     s
7167c657876SArnaldo Carvalho de Melo      --------
7177c657876SArnaldo Carvalho de Melo      R * f(p)
7187c657876SArnaldo Carvalho de Melo 
7197c657876SArnaldo Carvalho de Melo where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
7207c657876SArnaldo Carvalho de Melo 
7217c657876SArnaldo Carvalho de Melo Function parameters:
7227c657876SArnaldo Carvalho de Melo s - bytes
7237c657876SArnaldo Carvalho de Melo R - RTT in usecs
7247c657876SArnaldo Carvalho de Melo p - loss rate (decimal fraction multiplied by 1,000,000)
7257c657876SArnaldo Carvalho de Melo 
7267c657876SArnaldo Carvalho de Melo Returns Xcalc in bytes per second
7277c657876SArnaldo Carvalho de Melo 
7287c657876SArnaldo Carvalho de Melo DON'T alter this code unless you run test cases against it as the code
7297c657876SArnaldo Carvalho de Melo has been manipulated to stop underflow/overlow.
7307c657876SArnaldo Carvalho de Melo 
7317c657876SArnaldo Carvalho de Melo */
7327c657876SArnaldo Carvalho de Melo static u32 ccid3_calc_x(u16 s, u32 R, u32 p)
7337c657876SArnaldo Carvalho de Melo {
7347c657876SArnaldo Carvalho de Melo 	int index;
7357c657876SArnaldo Carvalho de Melo 	u32 f;
7367c657876SArnaldo Carvalho de Melo 	u64 tmp1, tmp2;
7377c657876SArnaldo Carvalho de Melo 
7387c657876SArnaldo Carvalho de Melo 	if (p < CALCX_SPLIT)
7397c657876SArnaldo Carvalho de Melo 		index = (p / (CALCX_SPLIT / CALCX_ARRSIZE)) - 1;
7407c657876SArnaldo Carvalho de Melo 	else
7417c657876SArnaldo Carvalho de Melo 		index = (p / (1000000 / CALCX_ARRSIZE)) - 1;
7427c657876SArnaldo Carvalho de Melo 
7437c657876SArnaldo Carvalho de Melo 	if (index < 0)
7447c657876SArnaldo Carvalho de Melo 		/* p should be 0 unless there is a bug in my code */
7457c657876SArnaldo Carvalho de Melo 		index = 0;
7467c657876SArnaldo Carvalho de Melo 
7477c657876SArnaldo Carvalho de Melo 	if (R == 0)
7487c657876SArnaldo Carvalho de Melo 		R = 1; /* RTT can't be zero or else divide by zero */
7497c657876SArnaldo Carvalho de Melo 
7507c657876SArnaldo Carvalho de Melo 	BUG_ON(index >= CALCX_ARRSIZE);
7517c657876SArnaldo Carvalho de Melo 
7527c657876SArnaldo Carvalho de Melo 	if (p >= CALCX_SPLIT)
7537c657876SArnaldo Carvalho de Melo 		f = calcx_lookup[index][0];
7547c657876SArnaldo Carvalho de Melo 	else
7557c657876SArnaldo Carvalho de Melo 		f = calcx_lookup[index][1];
7567c657876SArnaldo Carvalho de Melo 
7577c657876SArnaldo Carvalho de Melo 	tmp1 = ((u64)s * 100000000);
7587c657876SArnaldo Carvalho de Melo 	tmp2 = ((u64)R * (u64)f);
7597c657876SArnaldo Carvalho de Melo 	do_div(tmp2,10000);
7607c657876SArnaldo Carvalho de Melo 	do_div(tmp1,tmp2);
7617c657876SArnaldo Carvalho de Melo 	/* don't alter above math unless you test due to overflow on 32 bit */
7627c657876SArnaldo Carvalho de Melo 
7637c657876SArnaldo Carvalho de Melo 	return (u32)tmp1;
7647c657876SArnaldo Carvalho de Melo }
7657c657876SArnaldo Carvalho de Melo 
7667c657876SArnaldo Carvalho de Melo /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
7677c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
7687c657876SArnaldo Carvalho de Melo {
7697c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK)
7707c657876SArnaldo Carvalho de Melo 		return;
7717c657876SArnaldo Carvalho de Melo 	/* if no feedback spec says t_ipi is 1 second (set elsewhere and then
7727c657876SArnaldo Carvalho de Melo 	 * doubles after every no feedback timer (separate function) */
7737c657876SArnaldo Carvalho de Melo 
7747c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x < 10) {
7757c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n");
7767c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 10;
7777c657876SArnaldo Carvalho de Melo 	}
7787c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000)
7797c657876SArnaldo Carvalho de Melo 		/ (hctx->ccid3hctx_x / 10);
7807c657876SArnaldo Carvalho de Melo 	/* reason for above maths with 10 in there is to avoid 32 bit
7817c657876SArnaldo Carvalho de Melo 	 * overflow for jumbo packets */
7827c657876SArnaldo Carvalho de Melo 
7837c657876SArnaldo Carvalho de Melo }
7847c657876SArnaldo Carvalho de Melo 
7857c657876SArnaldo Carvalho de Melo /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
7867c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
7877c657876SArnaldo Carvalho de Melo {
7887c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN);
7897c657876SArnaldo Carvalho de Melo 
7907c657876SArnaldo Carvalho de Melo }
7917c657876SArnaldo Carvalho de Melo 
7927c657876SArnaldo Carvalho de Melo /*
7937c657876SArnaldo Carvalho de Melo  * Update X by
7947c657876SArnaldo Carvalho de Melo  *    If (p > 0)
7957c657876SArnaldo Carvalho de Melo  *       x_calc = calcX(s, R, p);
7967c657876SArnaldo Carvalho de Melo  *       X = max(min(X_calc, 2 * X_recv), s / t_mbi);
7977c657876SArnaldo Carvalho de Melo  *    Else
7987c657876SArnaldo Carvalho de Melo  *       If (now - tld >= R)
7997c657876SArnaldo Carvalho de Melo  *          X = max(min(2 * X, 2 * X_recv), s / R);
8007c657876SArnaldo Carvalho de Melo  *          tld = now;
8017c657876SArnaldo Carvalho de Melo  */
8027c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_update_x(struct sock *sk)
8037c657876SArnaldo Carvalho de Melo {
8047c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
8057c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
8067c657876SArnaldo Carvalho de Melo 
8077c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {  /* to avoid large error in calcX */
8087c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x_calc = ccid3_calc_x(hctx->ccid3hctx_s,
8097c657876SArnaldo Carvalho de Melo 						      hctx->ccid3hctx_rtt,
8107c657876SArnaldo Carvalho de Melo 						      hctx->ccid3hctx_p);
8117c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc, 2 * hctx->ccid3hctx_x_recv),
8127c657876SArnaldo Carvalho de Melo 					       hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME);
8137c657876SArnaldo Carvalho de Melo 	} else if (now_delta(hctx->ccid3hctx_t_ld) >= hctx->ccid3hctx_rtt) {
8147c657876SArnaldo Carvalho de Melo 		u32 rtt = hctx->ccid3hctx_rtt;
8157c657876SArnaldo Carvalho de Melo 		if (rtt < 10) {
8167c657876SArnaldo Carvalho de Melo 			rtt = 10;
8177c657876SArnaldo Carvalho de Melo 		} /* avoid divide by zero below */
8187c657876SArnaldo Carvalho de Melo 
8197c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv, 2 * hctx->ccid3hctx_x),
8207c657876SArnaldo Carvalho de Melo 					(hctx->ccid3hctx_s * 100000) / (rtt / 10));
8217c657876SArnaldo Carvalho de Melo 		/* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */
8227c657876SArnaldo Carvalho de Melo 		do_gettimeofday(&hctx->ccid3hctx_t_ld);
8237c657876SArnaldo Carvalho de Melo 	}
8247c657876SArnaldo Carvalho de Melo 
8257c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x == 0) {
8267c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("ccid3hctx_x = 0!\n");
8277c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 1;
8287c657876SArnaldo Carvalho de Melo 	}
8297c657876SArnaldo Carvalho de Melo }
8307c657876SArnaldo Carvalho de Melo 
8317c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
8327c657876SArnaldo Carvalho de Melo {
8337c657876SArnaldo Carvalho de Melo 	struct sock *sk = (struct sock *)data;
8347c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
8357c657876SArnaldo Carvalho de Melo 	unsigned long next_tmout = 0;
8367c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
8377c657876SArnaldo Carvalho de Melo 	u32 rtt;
8387c657876SArnaldo Carvalho de Melo 
8397c657876SArnaldo Carvalho de Melo 	bh_lock_sock(sk);
8407c657876SArnaldo Carvalho de Melo 	if (sock_owned_by_user(sk)) {
8417c657876SArnaldo Carvalho de Melo 		/* Try again later. */
8427c657876SArnaldo Carvalho de Melo 		/* XXX: set some sensible MIB */
8437c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + HZ / 5);
8447c657876SArnaldo Carvalho de Melo 		goto out;
8457c657876SArnaldo Carvalho de Melo 	}
8467c657876SArnaldo Carvalho de Melo 
8477c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
8487c657876SArnaldo Carvalho de Melo 		       ccid3_tx_state_name(hctx->ccid3hctx_state));
8497c657876SArnaldo Carvalho de Melo 
8507c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x < 10) {
8517c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n");
8527c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 10;
8537c657876SArnaldo Carvalho de Melo 	}
8547c657876SArnaldo Carvalho de Melo 
8557c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
8567c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_TERM:
8577c657876SArnaldo Carvalho de Melo 		goto out;
8587c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
8597c657876SArnaldo Carvalho de Melo 		/* Halve send rate */
8607c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x /= 2;
8617c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME))
8627c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME;
8637c657876SArnaldo Carvalho de Melo 
8647c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d bytes/s\n",
8657c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, ccid3_tx_state_name(hctx->ccid3hctx_state),
8667c657876SArnaldo Carvalho de Melo 			       hctx->ccid3hctx_x);
8677c657876SArnaldo Carvalho de Melo 		next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000)
8687c657876SArnaldo Carvalho de Melo 				/ (hctx->ccid3hctx_x / 10), TFRC_INITIAL_TIMEOUT);
8697c657876SArnaldo Carvalho de Melo 		/* do above maths with 100000 and 10 to prevent overflow on 32 bit */
8707c657876SArnaldo Carvalho de Melo 		/* FIXME - not sure above calculation is correct. See section 5 of CCID3 11
8717c657876SArnaldo Carvalho de Melo 		 * should adjust tx_t_ipi and double that to achieve it really */
8727c657876SArnaldo Carvalho de Melo 		break;
8737c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
8747c657876SArnaldo Carvalho de Melo 		/* Check if IDLE since last timeout and recv rate is less than 4 packets per RTT */
8757c657876SArnaldo Carvalho de Melo 		rtt = hctx->ccid3hctx_rtt;
8767c657876SArnaldo Carvalho de Melo 		if (rtt < 10)
8777c657876SArnaldo Carvalho de Melo 			rtt = 10;
8787c657876SArnaldo Carvalho de Melo 		/* stop divide by zero below */
8797c657876SArnaldo Carvalho de Melo 		if (!hctx->ccid3hctx_idle || (hctx->ccid3hctx_x_recv >=
8807c657876SArnaldo Carvalho de Melo 				4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) {
8817c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", dccp_role(sk), sk,
8827c657876SArnaldo Carvalho de Melo 				       ccid3_tx_state_name(hctx->ccid3hctx_state));
8837c657876SArnaldo Carvalho de Melo 			/* Halve sending rate */
8847c657876SArnaldo Carvalho de Melo 
8857c657876SArnaldo Carvalho de Melo 			/*  If (X_calc > 2 * X_recv)
8867c657876SArnaldo Carvalho de Melo 			 *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
8877c657876SArnaldo Carvalho de Melo 			 *  Else
8887c657876SArnaldo Carvalho de Melo 			 *    X_recv = X_calc / 4;
8897c657876SArnaldo Carvalho de Melo 			 */
8907c657876SArnaldo Carvalho de Melo 			BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && hctx->ccid3hctx_x_calc == 0);
8917c657876SArnaldo Carvalho de Melo 
8927c657876SArnaldo Carvalho de Melo 			/* check also if p is zero -> x_calc is infinity? */
8937c657876SArnaldo Carvalho de Melo 			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
8947c657876SArnaldo Carvalho de Melo 			    hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
8957c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
8967c657876SArnaldo Carvalho de Melo 								    hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
8977c657876SArnaldo Carvalho de Melo 			else
8987c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
8997c657876SArnaldo Carvalho de Melo 
9007c657876SArnaldo Carvalho de Melo 			/* Update sending rate */
9017c657876SArnaldo Carvalho de Melo 			ccid3_hc_tx_update_x(sk);
9027c657876SArnaldo Carvalho de Melo 		}
9037c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x == 0) {
9047c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n");
9057c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = 10;
9067c657876SArnaldo Carvalho de Melo 		}
9077c657876SArnaldo Carvalho de Melo 		/* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
908c68e64cfSArnaldo Carvalho de Melo 		next_tmout = max_t(u32, hctx->ccid3hctx_t_rto,
9097c657876SArnaldo Carvalho de Melo 				   2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10));
9107c657876SArnaldo Carvalho de Melo 		break;
9117c657876SArnaldo Carvalho de Melo 	default:
9127c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
9137c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
9147c657876SArnaldo Carvalho de Melo 		dump_stack();
9157c657876SArnaldo Carvalho de Melo 		goto out;
9167c657876SArnaldo Carvalho de Melo 	}
9177c657876SArnaldo Carvalho de Melo 
9187c657876SArnaldo Carvalho de Melo 	sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
9197c657876SArnaldo Carvalho de Melo 			jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
9207c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_idle = 1;
9217c657876SArnaldo Carvalho de Melo out:
9227c657876SArnaldo Carvalho de Melo 	bh_unlock_sock(sk);
9237c657876SArnaldo Carvalho de Melo 	sock_put(sk);
9247c657876SArnaldo Carvalho de Melo }
9257c657876SArnaldo Carvalho de Melo 
92627258ee5SArnaldo Carvalho de Melo static int ccid3_hc_tx_send_packet(struct sock *sk,
92727258ee5SArnaldo Carvalho de Melo 				   struct sk_buff *skb, int len)
9287c657876SArnaldo Carvalho de Melo {
9297c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
9307c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
9318c60f3faSArnaldo Carvalho de Melo 	struct dccp_tx_hist_entry *new_packet;
9327c657876SArnaldo Carvalho de Melo 	struct timeval now;
93327258ee5SArnaldo Carvalho de Melo 	long delay;
9347c657876SArnaldo Carvalho de Melo 	int rc = -ENOTCONN;
9357c657876SArnaldo Carvalho de Melo 
9367c657876SArnaldo Carvalho de Melo //	ccid3_pr_debug("%s, sk=%p, skb=%p, len=%d\n", dccp_role(sk), sk, skb, len);
9377c657876SArnaldo Carvalho de Melo 	/*
9387c657876SArnaldo Carvalho de Melo 	 * check if pure ACK or Terminating */
9397c657876SArnaldo Carvalho de Melo 	/* XXX: We only call this function for DATA and DATAACK, on, these packets can have
9407c657876SArnaldo Carvalho de Melo 	 * zero length, but why the comment about "pure ACK"?
9417c657876SArnaldo Carvalho de Melo 	 */
9427c657876SArnaldo Carvalho de Melo 	if (hctx == NULL || len == 0 || hctx->ccid3hctx_state == TFRC_SSTATE_TERM)
9437c657876SArnaldo Carvalho de Melo 		goto out;
9447c657876SArnaldo Carvalho de Melo 
9457c657876SArnaldo Carvalho de Melo 	/* See if last packet allocated was not sent */
9468c60f3faSArnaldo Carvalho de Melo 	new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
9478c60f3faSArnaldo Carvalho de Melo 	if (new_packet == NULL || new_packet->dccphtx_sent) {
9488c60f3faSArnaldo Carvalho de Melo 		new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist, SLAB_ATOMIC);
9497c657876SArnaldo Carvalho de Melo 
9507c657876SArnaldo Carvalho de Melo 		rc = -ENOBUFS;
9517c657876SArnaldo Carvalho de Melo 		if (new_packet == NULL) {
9527c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, not enough mem to add "
9537c657876SArnaldo Carvalho de Melo 				       "to history, send refused\n", dccp_role(sk), sk);
9547c657876SArnaldo Carvalho de Melo 			goto out;
9557c657876SArnaldo Carvalho de Melo 		}
9567c657876SArnaldo Carvalho de Melo 
9578c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
9587c657876SArnaldo Carvalho de Melo 	}
9597c657876SArnaldo Carvalho de Melo 
9607c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
9617c657876SArnaldo Carvalho de Melo 
9627c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
9637c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
9647c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n", dccp_role(sk), sk,
9657c657876SArnaldo Carvalho de Melo 			       dp->dccps_gss);
9667c657876SArnaldo Carvalho de Melo 
9677c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
9687c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
9697c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
9707c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_last_win_count	 = 0;
9717c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_last_win_count = now;
9727c657876SArnaldo Carvalho de Melo 		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
9737c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT;
9747c657876SArnaldo Carvalho de Melo 
9757c657876SArnaldo Carvalho de Melo 		/* Set nominal send time for initial packet */
9767c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_nom = now;
9777c657876SArnaldo Carvalho de Melo 		(hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
9787c657876SArnaldo Carvalho de Melo 		timeval_fix(&(hctx->ccid3hctx_t_nom));
9797c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_delta(hctx);
9807c657876SArnaldo Carvalho de Melo 		rc = 0;
9817c657876SArnaldo Carvalho de Melo 		break;
9827c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
9837c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
98427258ee5SArnaldo Carvalho de Melo 		delay = (now_delta(hctx->ccid3hctx_t_nom) - hctx->ccid3hctx_delta);
98527258ee5SArnaldo Carvalho de Melo 		ccid3_pr_debug("send_packet delay=%ld\n", delay);
98627258ee5SArnaldo Carvalho de Melo 		delay /= -1000;
9877c657876SArnaldo Carvalho de Melo 		/* divide by -1000 is to convert to ms and get sign right */
98827258ee5SArnaldo Carvalho de Melo 		rc = delay > 0 ? -EAGAIN : 0;
9897c657876SArnaldo Carvalho de Melo 		break;
9907c657876SArnaldo Carvalho de Melo 	default:
9917c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
9927c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
9937c657876SArnaldo Carvalho de Melo 		dump_stack();
9947c657876SArnaldo Carvalho de Melo 		rc = -EINVAL;
9957c657876SArnaldo Carvalho de Melo 		break;
9967c657876SArnaldo Carvalho de Melo 	}
9977c657876SArnaldo Carvalho de Melo 
9987c657876SArnaldo Carvalho de Melo 	/* Can we send? if so add options and add to packet history */
9997c657876SArnaldo Carvalho de Melo 	if (rc == 0)
1000c1734376SArnaldo Carvalho de Melo 		new_packet->dccphtx_ccval =
10018c60f3faSArnaldo Carvalho de Melo 			DCCP_SKB_CB(skb)->dccpd_ccval =
10028c60f3faSArnaldo Carvalho de Melo 				hctx->ccid3hctx_last_win_count;
10037c657876SArnaldo Carvalho de Melo out:
10047c657876SArnaldo Carvalho de Melo 	return rc;
10057c657876SArnaldo Carvalho de Melo }
10067c657876SArnaldo Carvalho de Melo 
10077c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
10087c657876SArnaldo Carvalho de Melo {
10097c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
10107c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
10117c657876SArnaldo Carvalho de Melo 	struct timeval now;
10127c657876SArnaldo Carvalho de Melo 
10137c657876SArnaldo Carvalho de Melo 	BUG_ON(hctx == NULL);
10147c657876SArnaldo Carvalho de Melo 
10157c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
10167c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n",
10177c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
10187c657876SArnaldo Carvalho de Melo 		return;
10197c657876SArnaldo Carvalho de Melo 	}
10207c657876SArnaldo Carvalho de Melo 
10217c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
10227c657876SArnaldo Carvalho de Melo 
10237c657876SArnaldo Carvalho de Melo 	/* check if we have sent a data packet */
10247c657876SArnaldo Carvalho de Melo 	if (len > 0) {
10257c657876SArnaldo Carvalho de Melo 		unsigned long quarter_rtt;
10268c60f3faSArnaldo Carvalho de Melo 		struct dccp_tx_hist_entry *packet;
10277c657876SArnaldo Carvalho de Melo 
10288c60f3faSArnaldo Carvalho de Melo 		packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
10298c60f3faSArnaldo Carvalho de Melo 		if (packet == NULL) {
10307c657876SArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: packet doesn't exists in history!\n", __FUNCTION__);
10317c657876SArnaldo Carvalho de Melo 			return;
10327c657876SArnaldo Carvalho de Melo 		}
10338c60f3faSArnaldo Carvalho de Melo 		if (packet->dccphtx_sent) {
10347c657876SArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: no unsent packet in history!\n", __FUNCTION__);
10357c657876SArnaldo Carvalho de Melo 			return;
10367c657876SArnaldo Carvalho de Melo 		}
10378c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_tstamp = now;
10388c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_seqno  = dp->dccps_gss;
10398c60f3faSArnaldo Carvalho de Melo #if 0
10408c60f3faSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seqno=%llu inserted!\n",
10418c60f3faSArnaldo Carvalho de Melo 			       dccp_role(sk), sk, packet->dccphtx_seqno);
10428c60f3faSArnaldo Carvalho de Melo #endif
10437c657876SArnaldo Carvalho de Melo 		/*
10447c657876SArnaldo Carvalho de Melo 		 * Check if win_count have changed */
10457c657876SArnaldo Carvalho de Melo 		/* COMPLIANCE_BEGIN
10467c657876SArnaldo Carvalho de Melo 		 * Algorithm in "8.1. Window Counter Valuer" in draft-ietf-dccp-ccid3-11.txt
10477c657876SArnaldo Carvalho de Melo 		 */
10487c657876SArnaldo Carvalho de Melo 		quarter_rtt = now_delta(hctx->ccid3hctx_t_last_win_count) / (hctx->ccid3hctx_rtt / 4);
10497c657876SArnaldo Carvalho de Melo 		if (quarter_rtt > 0) {
10507c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_last_win_count = now;
10517c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_last_win_count	 = (hctx->ccid3hctx_last_win_count +
10527c657876SArnaldo Carvalho de Melo 							    min_t(unsigned long, quarter_rtt, 5)) % 16;
10537c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, window changed from %u to %u!\n",
10547c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
1055c1734376SArnaldo Carvalho de Melo 				       packet->dccphtx_ccval,
10567c657876SArnaldo Carvalho de Melo 				       hctx->ccid3hctx_last_win_count);
10577c657876SArnaldo Carvalho de Melo 		}
10587c657876SArnaldo Carvalho de Melo 		/* COMPLIANCE_END */
10597c657876SArnaldo Carvalho de Melo #if 0
10607c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, packet sent (%llu,%u)\n",
10617c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
10628c60f3faSArnaldo Carvalho de Melo 			       packet->dccphtx_seqno,
1063c1734376SArnaldo Carvalho de Melo 			       packet->dccphtx_ccval);
10647c657876SArnaldo Carvalho de Melo #endif
10657c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_idle = 0;
1066c1734376SArnaldo Carvalho de Melo 		packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
10678c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_sent = 1;
10687c657876SArnaldo Carvalho de Melo 	} else
10697c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
10707c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, dp->dccps_gss);
10717c657876SArnaldo Carvalho de Melo 
10727c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
10737c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
10747c657876SArnaldo Carvalho de Melo 		/* if first wasn't pure ack */
10757c657876SArnaldo Carvalho de Melo 		if (len != 0)
10767c657876SArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: %s, First packet sent is noted as a data packet\n",
10777c657876SArnaldo Carvalho de Melo 			       __FUNCTION__, dccp_role(sk));
10787c657876SArnaldo Carvalho de Melo 		return;
10797c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
10807c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
10817c657876SArnaldo Carvalho de Melo 		if (len > 0) {
10827c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_nom = now;
10837c657876SArnaldo Carvalho de Melo 			ccid3_calc_new_t_ipi(hctx);
10847c657876SArnaldo Carvalho de Melo 			ccid3_calc_new_delta(hctx);
10857c657876SArnaldo Carvalho de Melo 			(hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
10867c657876SArnaldo Carvalho de Melo 			timeval_fix(&(hctx->ccid3hctx_t_nom));
10877c657876SArnaldo Carvalho de Melo 		}
10887c657876SArnaldo Carvalho de Melo 		break;
10897c657876SArnaldo Carvalho de Melo 	default:
10907c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
10917c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
10927c657876SArnaldo Carvalho de Melo 		dump_stack();
10937c657876SArnaldo Carvalho de Melo 		break;
10947c657876SArnaldo Carvalho de Melo 	}
10957c657876SArnaldo Carvalho de Melo }
10967c657876SArnaldo Carvalho de Melo 
10977c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
10987c657876SArnaldo Carvalho de Melo {
10997c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
11007c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
11017c657876SArnaldo Carvalho de Melo 	struct ccid3_options_received *opt_recv;
11028c60f3faSArnaldo Carvalho de Melo 	struct dccp_tx_hist_entry *packet;
11037c657876SArnaldo Carvalho de Melo 	unsigned long next_tmout;
11041bc09869SIan McDonald 	u32 t_elapsed;
11057c657876SArnaldo Carvalho de Melo 	u32 pinv;
11067c657876SArnaldo Carvalho de Melo 	u32 x_recv;
11077c657876SArnaldo Carvalho de Melo 	u32 r_sample;
11087c657876SArnaldo Carvalho de Melo #if 0
11097c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p(%s), skb=%p(%s)\n",
11107c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, dccp_state_name(sk->sk_state),
11117c657876SArnaldo Carvalho de Melo 		       skb, dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
11127c657876SArnaldo Carvalho de Melo #endif
11137c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
11147c657876SArnaldo Carvalho de Melo 		return;
11157c657876SArnaldo Carvalho de Melo 
11167c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
11177c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, received a packet when terminating!\n", dccp_role(sk), sk);
11187c657876SArnaldo Carvalho de Melo 		return;
11197c657876SArnaldo Carvalho de Melo 	}
11207c657876SArnaldo Carvalho de Melo 
11217c657876SArnaldo Carvalho de Melo 	/* we are only interested in ACKs */
11227c657876SArnaldo Carvalho de Melo 	if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
11237c657876SArnaldo Carvalho de Melo 	      DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
11247c657876SArnaldo Carvalho de Melo 		return;
11257c657876SArnaldo Carvalho de Melo 
11267c657876SArnaldo Carvalho de Melo 	opt_recv = &hctx->ccid3hctx_options_received;
11277c657876SArnaldo Carvalho de Melo 
11287c657876SArnaldo Carvalho de Melo 	t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
11297c657876SArnaldo Carvalho de Melo 	x_recv = opt_recv->ccid3or_receive_rate;
11307c657876SArnaldo Carvalho de Melo 	pinv = opt_recv->ccid3or_loss_event_rate;
11317c657876SArnaldo Carvalho de Melo 
11327c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
11337c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
11347c657876SArnaldo Carvalho de Melo 		/* FIXME: what to do here? */
11357c657876SArnaldo Carvalho de Melo 		return;
11367c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
11377c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
11387c657876SArnaldo Carvalho de Melo 		/* Calculate new round trip sample by
11397c657876SArnaldo Carvalho de Melo 		 * R_sample = (now - t_recvdata) - t_delay */
11407c657876SArnaldo Carvalho de Melo 		/* get t_recvdata from history */
11418c60f3faSArnaldo Carvalho de Melo 		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
11428c60f3faSArnaldo Carvalho de Melo 						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
11437c657876SArnaldo Carvalho de Melo 		if (packet == NULL) {
11447c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't exist in history!\n",
11457c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk, DCCP_SKB_CB(skb)->dccpd_ack_seq,
11467c657876SArnaldo Carvalho de Melo 				       dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
11477c657876SArnaldo Carvalho de Melo 			return;
11487c657876SArnaldo Carvalho de Melo 		}
11497c657876SArnaldo Carvalho de Melo 
11507c657876SArnaldo Carvalho de Melo 		/* Update RTT */
11518c60f3faSArnaldo Carvalho de Melo 		r_sample = now_delta(packet->dccphtx_tstamp);
11527c657876SArnaldo Carvalho de Melo 		/* FIXME: */
11537c657876SArnaldo Carvalho de Melo 		// r_sample -= usecs_to_jiffies(t_elapsed * 10);
11547c657876SArnaldo Carvalho de Melo 
11557c657876SArnaldo Carvalho de Melo 		/* Update RTT estimate by
11567c657876SArnaldo Carvalho de Melo 		 * If (No feedback recv)
11577c657876SArnaldo Carvalho de Melo 		 *    R = R_sample;
11587c657876SArnaldo Carvalho de Melo 		 * Else
11597c657876SArnaldo Carvalho de Melo 		 *    R = q * R + (1 - q) * R_sample;
11607c657876SArnaldo Carvalho de Melo 		 *
11617c657876SArnaldo Carvalho de Melo 		 * q is a constant, RFC 3448 recomments 0.9
11627c657876SArnaldo Carvalho de Melo 		 */
11637c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
11647c657876SArnaldo Carvalho de Melo 			ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
11657c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = r_sample;
11667c657876SArnaldo Carvalho de Melo 		} else
11677c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + r_sample / 10;
11687c657876SArnaldo Carvalho de Melo 
11697c657876SArnaldo Carvalho de Melo 		/*
11707c657876SArnaldo Carvalho de Melo 		 * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent
11717c657876SArnaldo Carvalho de Melo 		 *      implemention of the new window count.
11727c657876SArnaldo Carvalho de Melo 		 */
11737c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_rtt < 4)
11747c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = 4;
11757c657876SArnaldo Carvalho de Melo 
11767c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, r_sample=%us\n",
11777c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
11787c657876SArnaldo Carvalho de Melo 			       hctx->ccid3hctx_rtt,
11797c657876SArnaldo Carvalho de Melo 			       r_sample);
11807c657876SArnaldo Carvalho de Melo 
11817c657876SArnaldo Carvalho de Melo 		/* Update timeout interval */
1182c68e64cfSArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
1183cef07fd6SArnaldo Carvalho de Melo 					      USEC_PER_SEC);
11847c657876SArnaldo Carvalho de Melo 
11857c657876SArnaldo Carvalho de Melo 		/* Update receive rate */
11867c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x_recv = x_recv;   /* x_recv in bytes per second */
11877c657876SArnaldo Carvalho de Melo 
11887c657876SArnaldo Carvalho de Melo 		/* Update loss event rate */
11897c657876SArnaldo Carvalho de Melo 		if (pinv == ~0 || pinv == 0)
11907c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_p = 0;
11917c657876SArnaldo Carvalho de Melo 		else {
11927c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_p = 1000000 / pinv;
11937c657876SArnaldo Carvalho de Melo 
11947c657876SArnaldo Carvalho de Melo 			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
11957c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_p = TFRC_SMALLEST_P;
11967c657876SArnaldo Carvalho de Melo 				ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", dccp_role(sk), sk);
11977c657876SArnaldo Carvalho de Melo 			}
11987c657876SArnaldo Carvalho de Melo 		}
11997c657876SArnaldo Carvalho de Melo 
12007c657876SArnaldo Carvalho de Melo 		/* unschedule no feedback timer */
12017c657876SArnaldo Carvalho de Melo 		sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
12027c657876SArnaldo Carvalho de Melo 
12037c657876SArnaldo Carvalho de Melo 		/* Update sending rate */
12047c657876SArnaldo Carvalho de Melo 		ccid3_hc_tx_update_x(sk);
12057c657876SArnaldo Carvalho de Melo 
12067c657876SArnaldo Carvalho de Melo 		/* Update next send time */
12077c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_t_ipi > (hctx->ccid3hctx_t_nom).tv_usec) {
1208cef07fd6SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_nom.tv_usec += USEC_PER_SEC;
12097c657876SArnaldo Carvalho de Melo 			(hctx->ccid3hctx_t_nom).tv_sec--;
12107c657876SArnaldo Carvalho de Melo 		}
12117c657876SArnaldo Carvalho de Melo 		/* FIXME - if no feedback then t_ipi can go > 1 second */
12127c657876SArnaldo Carvalho de Melo 		(hctx->ccid3hctx_t_nom).tv_usec -= hctx->ccid3hctx_t_ipi;
12137c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_t_ipi(hctx);
12147c657876SArnaldo Carvalho de Melo 		(hctx->ccid3hctx_t_nom).tv_usec += hctx->ccid3hctx_t_ipi;
12157c657876SArnaldo Carvalho de Melo 		timeval_fix(&(hctx->ccid3hctx_t_nom));
12167c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_delta(hctx);
12177c657876SArnaldo Carvalho de Melo 
12187c657876SArnaldo Carvalho de Melo 		/* remove all packets older than the one acked from history */
12198c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_purge_older(ccid3_tx_hist,
12208c60f3faSArnaldo Carvalho de Melo 					 &hctx->ccid3hctx_hist, packet);
12218c60f3faSArnaldo Carvalho de Melo 
12227c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x < 10) {
12237c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx->ccid3hctx_x < 10\n");
12247c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = 10;
12257c657876SArnaldo Carvalho de Melo 		}
12267c657876SArnaldo Carvalho de Melo 		/* to prevent divide by zero below */
12277c657876SArnaldo Carvalho de Melo 
12287c657876SArnaldo Carvalho de Melo 		/* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
1229c68e64cfSArnaldo Carvalho de Melo 		next_tmout = max(hctx->ccid3hctx_t_rto,
12308c60f3faSArnaldo Carvalho de Melo 				 (2 * (hctx->ccid3hctx_s * 100000) /
12318c60f3faSArnaldo Carvalho de Melo 				  (hctx->ccid3hctx_x / 10)));
12327c657876SArnaldo Carvalho de Melo 		/* maths with 100000 and 10 is to prevent overflow with 32 bit */
12337c657876SArnaldo Carvalho de Melo 
12347c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to expire in %lu jiffies (%luus)\n",
12357c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, usecs_to_jiffies(next_tmout), next_tmout);
12367c657876SArnaldo Carvalho de Melo 
12377c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
12387c657876SArnaldo Carvalho de Melo 				jiffies + max_t(u32,1,usecs_to_jiffies(next_tmout)));
12397c657876SArnaldo Carvalho de Melo 
12407c657876SArnaldo Carvalho de Melo 		/* set idle flag */
12417c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_idle = 1;
12427c657876SArnaldo Carvalho de Melo 		break;
12437c657876SArnaldo Carvalho de Melo 	default:
12447c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
12457c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
12467c657876SArnaldo Carvalho de Melo 		dump_stack();
12477c657876SArnaldo Carvalho de Melo 		break;
12487c657876SArnaldo Carvalho de Melo 	}
12497c657876SArnaldo Carvalho de Melo }
12507c657876SArnaldo Carvalho de Melo 
12517c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
12527c657876SArnaldo Carvalho de Melo {
12537c657876SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
12547c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
12557c657876SArnaldo Carvalho de Melo 
12567c657876SArnaldo Carvalho de Melo 	if (hctx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
12577c657876SArnaldo Carvalho de Melo 		return;
12587c657876SArnaldo Carvalho de Melo 
12597c657876SArnaldo Carvalho de Melo 	 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
12607c657876SArnaldo Carvalho de Melo }
12617c657876SArnaldo Carvalho de Melo 
12627c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
12637c657876SArnaldo Carvalho de Melo 				   unsigned char len, u16 idx, unsigned char *value)
12647c657876SArnaldo Carvalho de Melo {
12657c657876SArnaldo Carvalho de Melo 	int rc = 0;
12667c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
12677c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
12687c657876SArnaldo Carvalho de Melo 	struct ccid3_options_received *opt_recv;
12697c657876SArnaldo Carvalho de Melo 
12707c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
12717c657876SArnaldo Carvalho de Melo 		return 0;
12727c657876SArnaldo Carvalho de Melo 
12737c657876SArnaldo Carvalho de Melo 	opt_recv = &hctx->ccid3hctx_options_received;
12747c657876SArnaldo Carvalho de Melo 
12757c657876SArnaldo Carvalho de Melo 	if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
12767c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_seqno		     = dp->dccps_gsr;
12777c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_event_rate    = ~0;
12787c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_idx = 0;
12797c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_len = 0;
12807c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_receive_rate	     = 0;
12817c657876SArnaldo Carvalho de Melo 	}
12827c657876SArnaldo Carvalho de Melo 
12837c657876SArnaldo Carvalho de Melo 	switch (option) {
12847c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_LOSS_EVENT_RATE:
12857c657876SArnaldo Carvalho de Melo 		if (len != 4) {
12867c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_LOSS_EVENT_RATE\n",
12877c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
12887c657876SArnaldo Carvalho de Melo 			rc = -EINVAL;
12897c657876SArnaldo Carvalho de Melo 		} else {
12907c657876SArnaldo Carvalho de Melo 			opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
12917c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
12927c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
12937c657876SArnaldo Carvalho de Melo 				       opt_recv->ccid3or_loss_event_rate);
12947c657876SArnaldo Carvalho de Melo 		}
12957c657876SArnaldo Carvalho de Melo 		break;
12967c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_LOSS_INTERVALS:
12977c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_idx = idx;
12987c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_len = len;
12997c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
13007c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
13017c657876SArnaldo Carvalho de Melo 			       opt_recv->ccid3or_loss_intervals_idx,
13027c657876SArnaldo Carvalho de Melo 			       opt_recv->ccid3or_loss_intervals_len);
13037c657876SArnaldo Carvalho de Melo 		break;
13047c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_RECEIVE_RATE:
13057c657876SArnaldo Carvalho de Melo 		if (len != 4) {
13067c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, invalid len for TFRC_OPT_RECEIVE_RATE\n",
13077c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
13087c657876SArnaldo Carvalho de Melo 			rc = -EINVAL;
13097c657876SArnaldo Carvalho de Melo 		} else {
13107c657876SArnaldo Carvalho de Melo 			opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
13117c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
13127c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
13137c657876SArnaldo Carvalho de Melo 				       opt_recv->ccid3or_receive_rate);
13147c657876SArnaldo Carvalho de Melo 		}
13157c657876SArnaldo Carvalho de Melo 		break;
13167c657876SArnaldo Carvalho de Melo 	}
13177c657876SArnaldo Carvalho de Melo 
13187c657876SArnaldo Carvalho de Melo 	return rc;
13197c657876SArnaldo Carvalho de Melo }
13207c657876SArnaldo Carvalho de Melo 
13217c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_init(struct sock *sk)
13227c657876SArnaldo Carvalho de Melo {
13237c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13247c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx;
13257c657876SArnaldo Carvalho de Melo 
13267c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
13277c657876SArnaldo Carvalho de Melo 
13287c657876SArnaldo Carvalho de Melo 	hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx), gfp_any());
13297c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
13307c657876SArnaldo Carvalho de Melo 		return -ENOMEM;
13317c657876SArnaldo Carvalho de Melo 
13327c657876SArnaldo Carvalho de Melo 	memset(hctx, 0, sizeof(*hctx));
13337c657876SArnaldo Carvalho de Melo 
13347c657876SArnaldo Carvalho de Melo 	if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
13357c657876SArnaldo Carvalho de Melo 	    dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
13367c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size;
13377c657876SArnaldo Carvalho de Melo 	else
13387c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
13397c657876SArnaldo Carvalho de Melo 
13407c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_x     = hctx->ccid3hctx_s; /* set transmission rate to 1 packet per second */
13417c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_rtt   = 4; /* See ccid3_hc_tx_packet_sent win_count calculatation */
1342c68e64cfSArnaldo Carvalho de Melo 	hctx->ccid3hctx_t_rto = USEC_PER_SEC;
13437c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
13447c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
13457c657876SArnaldo Carvalho de Melo 	init_timer(&hctx->ccid3hctx_no_feedback_timer);
13467c657876SArnaldo Carvalho de Melo 
13477c657876SArnaldo Carvalho de Melo 	return 0;
13487c657876SArnaldo Carvalho de Melo }
13497c657876SArnaldo Carvalho de Melo 
13507c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_exit(struct sock *sk)
13517c657876SArnaldo Carvalho de Melo {
13527c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13537c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
13547c657876SArnaldo Carvalho de Melo 
13557c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
13567c657876SArnaldo Carvalho de Melo 	BUG_ON(hctx == NULL);
13577c657876SArnaldo Carvalho de Melo 
13587c657876SArnaldo Carvalho de Melo 	ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
13597c657876SArnaldo Carvalho de Melo 	sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
13607c657876SArnaldo Carvalho de Melo 
13617c657876SArnaldo Carvalho de Melo 	/* Empty packet history */
13628c60f3faSArnaldo Carvalho de Melo 	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
13637c657876SArnaldo Carvalho de Melo 
13647c657876SArnaldo Carvalho de Melo 	kfree(dp->dccps_hc_tx_ccid_private);
13657c657876SArnaldo Carvalho de Melo 	dp->dccps_hc_tx_ccid_private = NULL;
13667c657876SArnaldo Carvalho de Melo }
13677c657876SArnaldo Carvalho de Melo 
13687c657876SArnaldo Carvalho de Melo /*
13697c657876SArnaldo Carvalho de Melo  * RX Half Connection methods
13707c657876SArnaldo Carvalho de Melo  */
13717c657876SArnaldo Carvalho de Melo 
13727c657876SArnaldo Carvalho de Melo /* TFRC receiver states */
13737c657876SArnaldo Carvalho de Melo enum ccid3_hc_rx_states {
13747c657876SArnaldo Carvalho de Melo        	TFRC_RSTATE_NO_DATA = 1,
13757c657876SArnaldo Carvalho de Melo 	TFRC_RSTATE_DATA,
13767c657876SArnaldo Carvalho de Melo 	TFRC_RSTATE_TERM    = 127,
13777c657876SArnaldo Carvalho de Melo };
13787c657876SArnaldo Carvalho de Melo 
13797c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG
13807c657876SArnaldo Carvalho de Melo static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
13817c657876SArnaldo Carvalho de Melo {
13827c657876SArnaldo Carvalho de Melo 	static char *ccid3_rx_state_names[] = {
13837c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_NO_DATA] = "NO_DATA",
13847c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_DATA]    = "DATA",
13857c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_TERM]    = "TERM",
13867c657876SArnaldo Carvalho de Melo 	};
13877c657876SArnaldo Carvalho de Melo 
13887c657876SArnaldo Carvalho de Melo 	return ccid3_rx_state_names[state];
13897c657876SArnaldo Carvalho de Melo }
13907c657876SArnaldo Carvalho de Melo #endif
13917c657876SArnaldo Carvalho de Melo 
13927c657876SArnaldo Carvalho de Melo static inline void ccid3_hc_rx_set_state(struct sock *sk, enum ccid3_hc_rx_states state)
13937c657876SArnaldo Carvalho de Melo {
13947c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13957c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
13967c657876SArnaldo Carvalho de Melo 	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
13977c657876SArnaldo Carvalho de Melo 
13987c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
13997c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate), ccid3_rx_state_name(state));
14007c657876SArnaldo Carvalho de Melo 	WARN_ON(state == oldstate);
14017c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_state = state;
14027c657876SArnaldo Carvalho de Melo }
14037c657876SArnaldo Carvalho de Melo 
14048c60f3faSArnaldo Carvalho de Melo static int ccid3_hc_rx_add_hist(struct sock *sk,
14058c60f3faSArnaldo Carvalho de Melo 				struct dccp_rx_hist_entry *packet)
14067c657876SArnaldo Carvalho de Melo {
14077c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
14087c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
14098c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *iter;
14107c657876SArnaldo Carvalho de Melo 	u8 num_later = 0;
14117c657876SArnaldo Carvalho de Melo 
14128c60f3faSArnaldo Carvalho de Melo 	iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
14138c60f3faSArnaldo Carvalho de Melo 	if (iter == NULL)
14148c60f3faSArnaldo Carvalho de Melo 		dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
14157c657876SArnaldo Carvalho de Melo 	else {
14168c60f3faSArnaldo Carvalho de Melo 		const u64 seqno = packet->dccphrx_seqno;
14178c60f3faSArnaldo Carvalho de Melo 
14188c60f3faSArnaldo Carvalho de Melo 		if (after48(seqno, iter->dccphrx_seqno))
14198c60f3faSArnaldo Carvalho de Melo 			dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
14207c657876SArnaldo Carvalho de Melo 		else {
14218c60f3faSArnaldo Carvalho de Melo 			if (dccp_rx_hist_entry_data_packet(iter))
14227c657876SArnaldo Carvalho de Melo 				num_later = 1;
14237c657876SArnaldo Carvalho de Melo 
14248c60f3faSArnaldo Carvalho de Melo 			list_for_each_entry_continue(iter,
14258c60f3faSArnaldo Carvalho de Melo 						     &hcrx->ccid3hcrx_hist,
14268c60f3faSArnaldo Carvalho de Melo 						     dccphrx_node) {
14278c60f3faSArnaldo Carvalho de Melo 				if (after48(seqno, iter->dccphrx_seqno)) {
14288c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_add_entry(&iter->dccphrx_node,
14298c60f3faSArnaldo Carvalho de Melo 							       packet);
14307c657876SArnaldo Carvalho de Melo 					goto trim_history;
14317c657876SArnaldo Carvalho de Melo 				}
14327c657876SArnaldo Carvalho de Melo 
14338c60f3faSArnaldo Carvalho de Melo 				if (dccp_rx_hist_entry_data_packet(iter))
14347c657876SArnaldo Carvalho de Melo 					num_later++;
14357c657876SArnaldo Carvalho de Melo 
14367c657876SArnaldo Carvalho de Melo 				if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
14378c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_entry_delete(ccid3_rx_hist, packet);
14387c657876SArnaldo Carvalho de Melo 					ccid3_pr_debug("%s, sk=%p, packet(%llu) already lost!\n",
14397c657876SArnaldo Carvalho de Melo 						       dccp_role(sk), sk, seqno);
14407c657876SArnaldo Carvalho de Melo 					return 1;
14417c657876SArnaldo Carvalho de Melo 				}
14427c657876SArnaldo Carvalho de Melo 			}
14437c657876SArnaldo Carvalho de Melo 
14447c657876SArnaldo Carvalho de Melo 			if (num_later < TFRC_RECV_NUM_LATE_LOSS)
14458c60f3faSArnaldo Carvalho de Melo 				dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist,
14468c60f3faSArnaldo Carvalho de Melo 						       packet);
14477c657876SArnaldo Carvalho de Melo 			/* FIXME: else what? should we destroy the packet like above? */
14487c657876SArnaldo Carvalho de Melo 		}
14497c657876SArnaldo Carvalho de Melo 	}
14507c657876SArnaldo Carvalho de Melo 
14517c657876SArnaldo Carvalho de Melo trim_history:
14527c657876SArnaldo Carvalho de Melo 	/* Trim history (remove all packets after the NUM_LATE_LOSS + 1 data packets) */
14537c657876SArnaldo Carvalho de Melo 	num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
14547c657876SArnaldo Carvalho de Melo 
14557c657876SArnaldo Carvalho de Melo 	if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
14568c60f3faSArnaldo Carvalho de Melo 		list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
14578c60f3faSArnaldo Carvalho de Melo 					 dccphrx_node) {
14587c657876SArnaldo Carvalho de Melo 			if (num_later == 0) {
14598c60f3faSArnaldo Carvalho de Melo 				list_del_init(&entry->dccphrx_node);
14608c60f3faSArnaldo Carvalho de Melo 				dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
14618c60f3faSArnaldo Carvalho de Melo 			} else if (dccp_rx_hist_entry_data_packet(entry))
14627c657876SArnaldo Carvalho de Melo 				--num_later;
14637c657876SArnaldo Carvalho de Melo 		}
14647c657876SArnaldo Carvalho de Melo 	} else {
14657c657876SArnaldo Carvalho de Melo 		int step = 0;
14667c657876SArnaldo Carvalho de Melo 		u8 win_count = 0; /* Not needed, but lets shut up gcc */
14677c657876SArnaldo Carvalho de Melo 		int tmp;
14687c657876SArnaldo Carvalho de Melo 		/*
14697c657876SArnaldo Carvalho de Melo 		 * We have no loss interval history so we need at least one
14707c657876SArnaldo Carvalho de Melo 		 * rtt:s of data packets to approximate rtt.
14717c657876SArnaldo Carvalho de Melo 		 */
14728c60f3faSArnaldo Carvalho de Melo 		list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
14738c60f3faSArnaldo Carvalho de Melo 					 dccphrx_node) {
14747c657876SArnaldo Carvalho de Melo 			if (num_later == 0) {
14757c657876SArnaldo Carvalho de Melo 				switch (step) {
14767c657876SArnaldo Carvalho de Melo 				case 0:
14777c657876SArnaldo Carvalho de Melo 					step = 1;
14787c657876SArnaldo Carvalho de Melo 					/* OK, find next data packet */
14797c657876SArnaldo Carvalho de Melo 					num_later = 1;
14807c657876SArnaldo Carvalho de Melo 					break;
14817c657876SArnaldo Carvalho de Melo 				case 1:
14827c657876SArnaldo Carvalho de Melo 					step = 2;
14837c657876SArnaldo Carvalho de Melo 					/* OK, find next data packet */
14847c657876SArnaldo Carvalho de Melo 					num_later = 1;
1485c1734376SArnaldo Carvalho de Melo 					win_count = entry->dccphrx_ccval;
14867c657876SArnaldo Carvalho de Melo 					break;
14877c657876SArnaldo Carvalho de Melo 				case 2:
1488c1734376SArnaldo Carvalho de Melo 					tmp = win_count - entry->dccphrx_ccval;
14897c657876SArnaldo Carvalho de Melo 					if (tmp < 0)
14907c657876SArnaldo Carvalho de Melo 						tmp += TFRC_WIN_COUNT_LIMIT;
14917c657876SArnaldo Carvalho de Melo 					if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
14927c657876SArnaldo Carvalho de Melo 						/* we have found a packet older than one rtt
14937c657876SArnaldo Carvalho de Melo 						 * remove the rest */
14947c657876SArnaldo Carvalho de Melo 						step = 3;
14957c657876SArnaldo Carvalho de Melo 					} else /* OK, find next data packet */
14967c657876SArnaldo Carvalho de Melo 						num_later = 1;
14977c657876SArnaldo Carvalho de Melo 					break;
14987c657876SArnaldo Carvalho de Melo 				case 3:
14998c60f3faSArnaldo Carvalho de Melo 					list_del_init(&entry->dccphrx_node);
15008c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
15017c657876SArnaldo Carvalho de Melo 					break;
15027c657876SArnaldo Carvalho de Melo 				}
15038c60f3faSArnaldo Carvalho de Melo 			} else if (dccp_rx_hist_entry_data_packet(entry))
15047c657876SArnaldo Carvalho de Melo 				--num_later;
15057c657876SArnaldo Carvalho de Melo 		}
15067c657876SArnaldo Carvalho de Melo 	}
15077c657876SArnaldo Carvalho de Melo 
15087c657876SArnaldo Carvalho de Melo 	return 0;
15097c657876SArnaldo Carvalho de Melo }
15107c657876SArnaldo Carvalho de Melo 
15117c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_send_feedback(struct sock *sk)
15127c657876SArnaldo Carvalho de Melo {
15137c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
15147c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
15158c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *packet;
15167c657876SArnaldo Carvalho de Melo 
15177c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
15187c657876SArnaldo Carvalho de Melo 
15197c657876SArnaldo Carvalho de Melo 	switch (hcrx->ccid3hcrx_state) {
15207c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_NO_DATA:
15217c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_x_recv = 0;
15227c657876SArnaldo Carvalho de Melo 		break;
15237c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_DATA: {
15247c657876SArnaldo Carvalho de Melo 		u32 delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
15257c657876SArnaldo Carvalho de Melo 
15267c657876SArnaldo Carvalho de Melo 		if (delta == 0)
15277c657876SArnaldo Carvalho de Melo 			delta = 1; /* to prevent divide by zero */
1528cef07fd6SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv *
1529cef07fd6SArnaldo Carvalho de Melo 					  USEC_PER_SEC) / delta;
15307c657876SArnaldo Carvalho de Melo 	}
15317c657876SArnaldo Carvalho de Melo 		break;
15327c657876SArnaldo Carvalho de Melo 	default:
15337c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
15347c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
15357c657876SArnaldo Carvalho de Melo 		dump_stack();
15367c657876SArnaldo Carvalho de Melo 		return;
15377c657876SArnaldo Carvalho de Melo 	}
15387c657876SArnaldo Carvalho de Melo 
15398c60f3faSArnaldo Carvalho de Melo 	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
15407c657876SArnaldo Carvalho de Melo 	if (packet == NULL) {
15417c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n",
15427c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk);
15437c657876SArnaldo Carvalho de Melo 		dump_stack();
15447c657876SArnaldo Carvalho de Melo 		return;
15457c657876SArnaldo Carvalho de Melo 	}
15467c657876SArnaldo Carvalho de Melo 
15477c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&(hcrx->ccid3hcrx_tstamp_last_feedback));
1548c1734376SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_last_counter	     = packet->dccphrx_ccval;
15498c60f3faSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_seqno_last_counter   = packet->dccphrx_seqno;
15507c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_bytes_recv	     = 0;
15517c657876SArnaldo Carvalho de Melo 
15527c657876SArnaldo Carvalho de Melo 	/* Convert to multiples of 10us */
15538c60f3faSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_elapsed_time = now_delta(packet->dccphrx_tstamp) / 10;
15547c657876SArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_p == 0)
15557c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_pinv = ~0;
15567c657876SArnaldo Carvalho de Melo 	else
15577c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
15587c657876SArnaldo Carvalho de Melo 	dccp_send_ack(sk);
15597c657876SArnaldo Carvalho de Melo }
15607c657876SArnaldo Carvalho de Melo 
15617c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
15627c657876SArnaldo Carvalho de Melo {
15637c657876SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
15644fded33bSArnaldo Carvalho de Melo 	u32 x_recv, pinv;
15657c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
15667c657876SArnaldo Carvalho de Melo 
15677c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
15687c657876SArnaldo Carvalho de Melo 		return;
15697c657876SArnaldo Carvalho de Melo 
15707c657876SArnaldo Carvalho de Melo 	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
15714fded33bSArnaldo Carvalho de Melo 
15724fded33bSArnaldo Carvalho de Melo 	if (dccp_packet_without_ack(skb))
15734fded33bSArnaldo Carvalho de Melo 		return;
15744fded33bSArnaldo Carvalho de Melo 
15754fded33bSArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_elapsed_time != 0)
15764fded33bSArnaldo Carvalho de Melo 		dccp_insert_option_elapsed_time(sk, skb,
15774fded33bSArnaldo Carvalho de Melo 						hcrx->ccid3hcrx_elapsed_time);
15784fded33bSArnaldo Carvalho de Melo 	dccp_insert_option_timestamp(sk, skb);
15794fded33bSArnaldo Carvalho de Melo 	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
15804fded33bSArnaldo Carvalho de Melo 	pinv   = htonl(hcrx->ccid3hcrx_pinv);
15814fded33bSArnaldo Carvalho de Melo 	dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
15824fded33bSArnaldo Carvalho de Melo 			   &pinv, sizeof(pinv));
15834fded33bSArnaldo Carvalho de Melo 	dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
15844fded33bSArnaldo Carvalho de Melo 			   &x_recv, sizeof(x_recv));
15857c657876SArnaldo Carvalho de Melo }
15867c657876SArnaldo Carvalho de Melo 
15877c657876SArnaldo Carvalho de Melo /* Weights used to calculate loss event rate */
15887c657876SArnaldo Carvalho de Melo /*
15897c657876SArnaldo Carvalho de Melo  * These are integers as per section 8 of RFC3448. We can then divide by 4 *
15907c657876SArnaldo Carvalho de Melo  * when we use it.
15917c657876SArnaldo Carvalho de Melo  */
1592a1d3a355SArnaldo Carvalho de Melo static const int ccid3_hc_rx_w[TFRC_RECV_IVAL_F_LENGTH] = {
1593a1d3a355SArnaldo Carvalho de Melo 	4, 4, 4, 4, 3, 2, 1, 1,
1594a1d3a355SArnaldo Carvalho de Melo };
15957c657876SArnaldo Carvalho de Melo 
15967c657876SArnaldo Carvalho de Melo /*
15977c657876SArnaldo Carvalho de Melo  * args: fvalue - function value to match
15987c657876SArnaldo Carvalho de Melo  * returns:  p  closest to that value
15997c657876SArnaldo Carvalho de Melo  *
16007c657876SArnaldo Carvalho de Melo  * both fvalue and p are multiplied by 1,000,000 to use ints
16017c657876SArnaldo Carvalho de Melo  */
1602a1d3a355SArnaldo Carvalho de Melo static u32 calcx_reverse_lookup(u32 fvalue) {
16037c657876SArnaldo Carvalho de Melo 	int ctr = 0;
16047c657876SArnaldo Carvalho de Melo 	int small;
16057c657876SArnaldo Carvalho de Melo 
16067c657876SArnaldo Carvalho de Melo 	if (fvalue < calcx_lookup[0][1])
16077c657876SArnaldo Carvalho de Melo 		return 0;
16087c657876SArnaldo Carvalho de Melo 	if (fvalue <= calcx_lookup[CALCX_ARRSIZE-1][1])
16097c657876SArnaldo Carvalho de Melo 		small = 1;
16107c657876SArnaldo Carvalho de Melo 	else if (fvalue > calcx_lookup[CALCX_ARRSIZE-1][0])
16117c657876SArnaldo Carvalho de Melo 		return 1000000;
16127c657876SArnaldo Carvalho de Melo 	else
16137c657876SArnaldo Carvalho de Melo 		small = 0;
16147c657876SArnaldo Carvalho de Melo 	while (fvalue > calcx_lookup[ctr][small])
16157c657876SArnaldo Carvalho de Melo 		ctr++;
16167c657876SArnaldo Carvalho de Melo 	if (small)
16177c657876SArnaldo Carvalho de Melo 		return (CALCX_SPLIT * ctr / CALCX_ARRSIZE);
16187c657876SArnaldo Carvalho de Melo 	else
16197c657876SArnaldo Carvalho de Melo 		return (1000000 * ctr / CALCX_ARRSIZE) ;
16207c657876SArnaldo Carvalho de Melo }
16217c657876SArnaldo Carvalho de Melo 
16227c657876SArnaldo Carvalho de Melo /* calculate first loss interval
16237c657876SArnaldo Carvalho de Melo  *
16247c657876SArnaldo Carvalho de Melo  * returns estimated loss interval in usecs */
16257c657876SArnaldo Carvalho de Melo 
16267c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
16277c657876SArnaldo Carvalho de Melo {
16287c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
16297c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
16308c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
16317c657876SArnaldo Carvalho de Melo 	u32 rtt, delta, x_recv, fval, p, tmp2;
1632a10cedd4SPatrick McHardy 	struct timeval tstamp = { 0 }, tmp_tv;
16337c657876SArnaldo Carvalho de Melo 	int interval = 0;
16347c657876SArnaldo Carvalho de Melo 	int win_count = 0;
16357c657876SArnaldo Carvalho de Melo 	int step = 0;
16367c657876SArnaldo Carvalho de Melo 	u64 tmp1;
16377c657876SArnaldo Carvalho de Melo 
16388c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
16398c60f3faSArnaldo Carvalho de Melo 				 dccphrx_node) {
16408c60f3faSArnaldo Carvalho de Melo 		if (dccp_rx_hist_entry_data_packet(entry)) {
16417c657876SArnaldo Carvalho de Melo 			tail = entry;
16427c657876SArnaldo Carvalho de Melo 
16437c657876SArnaldo Carvalho de Melo 			switch (step) {
16447c657876SArnaldo Carvalho de Melo 			case 0:
16458c60f3faSArnaldo Carvalho de Melo 				tstamp	  = entry->dccphrx_tstamp;
1646c1734376SArnaldo Carvalho de Melo 				win_count = entry->dccphrx_ccval;
16477c657876SArnaldo Carvalho de Melo 				step = 1;
16487c657876SArnaldo Carvalho de Melo 				break;
16497c657876SArnaldo Carvalho de Melo 			case 1:
1650c1734376SArnaldo Carvalho de Melo 				interval = win_count - entry->dccphrx_ccval;
16517c657876SArnaldo Carvalho de Melo 				if (interval < 0)
16527c657876SArnaldo Carvalho de Melo 					interval += TFRC_WIN_COUNT_LIMIT;
16537c657876SArnaldo Carvalho de Melo 				if (interval > 4)
16547c657876SArnaldo Carvalho de Melo 					goto found;
16557c657876SArnaldo Carvalho de Melo 				break;
16567c657876SArnaldo Carvalho de Melo 			}
16577c657876SArnaldo Carvalho de Melo 		}
16587c657876SArnaldo Carvalho de Melo 	}
16597c657876SArnaldo Carvalho de Melo 
16607c657876SArnaldo Carvalho de Melo 	if (step == 0) {
16617c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no data packets!\n",
16627c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk);
16637c657876SArnaldo Carvalho de Melo 		return ~0;
16647c657876SArnaldo Carvalho de Melo 	}
16657c657876SArnaldo Carvalho de Melo 
16667c657876SArnaldo Carvalho de Melo 	if (interval == 0) {
16677c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Could not find a win_count interval > 0. Defaulting to 1\n",
16687c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
16697c657876SArnaldo Carvalho de Melo 		interval = 1;
16707c657876SArnaldo Carvalho de Melo 	}
16717c657876SArnaldo Carvalho de Melo found:
16728c60f3faSArnaldo Carvalho de Melo 	timeval_sub(tstamp,tail->dccphrx_tstamp,&tmp_tv);
1673cef07fd6SArnaldo Carvalho de Melo 	rtt = (tmp_tv.tv_sec * USEC_PER_SEC + tmp_tv.tv_usec) * 4 / interval;
16747c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
16757c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, rtt);
16767c657876SArnaldo Carvalho de Melo 	if (rtt == 0)
16777c657876SArnaldo Carvalho de Melo 		rtt = 1;
16787c657876SArnaldo Carvalho de Melo 
16797c657876SArnaldo Carvalho de Melo 	delta = now_delta(hcrx->ccid3hcrx_tstamp_last_feedback);
16807c657876SArnaldo Carvalho de Melo 	if (delta == 0)
16817c657876SArnaldo Carvalho de Melo 		delta = 1;
16827c657876SArnaldo Carvalho de Melo 
1683cef07fd6SArnaldo Carvalho de Melo 	x_recv = (hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC) / delta;
16847c657876SArnaldo Carvalho de Melo 
16857c657876SArnaldo Carvalho de Melo 	tmp1 = (u64)x_recv * (u64)rtt;
16867c657876SArnaldo Carvalho de Melo 	do_div(tmp1,10000000);
16877c657876SArnaldo Carvalho de Melo 	tmp2 = (u32)tmp1;
16887c657876SArnaldo Carvalho de Melo 	fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
16897c657876SArnaldo Carvalho de Melo 	/* do not alter order above or you will get overflow on 32 bit */
16907c657876SArnaldo Carvalho de Melo 	p = calcx_reverse_lookup(fval);
16917c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied loss rate=%u\n",\
16927c657876SArnaldo Carvalho de Melo 			dccp_role(sk), sk, x_recv, p);
16937c657876SArnaldo Carvalho de Melo 
16947c657876SArnaldo Carvalho de Melo 	if (p == 0)
16957c657876SArnaldo Carvalho de Melo 		return ~0;
16967c657876SArnaldo Carvalho de Melo 	else
16977c657876SArnaldo Carvalho de Melo 		return 1000000 / p;
16987c657876SArnaldo Carvalho de Melo }
16997c657876SArnaldo Carvalho de Melo 
17007c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
17017c657876SArnaldo Carvalho de Melo {
17027c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
17037c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
17047c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *li_entry;
17057c657876SArnaldo Carvalho de Melo 
17067c657876SArnaldo Carvalho de Melo 	if (seq_loss != DCCP_MAX_SEQNO + 1) {
17077c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seq_loss=%llu, win_loss=%u, packet loss detected\n",
17087c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, seq_loss, win_loss);
17097c657876SArnaldo Carvalho de Melo 
17107c657876SArnaldo Carvalho de Melo 		if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
17117c657876SArnaldo Carvalho de Melo 			struct ccid3_loss_interval_hist_entry *li_tail = NULL;
17127c657876SArnaldo Carvalho de Melo 			int i;
17137c657876SArnaldo Carvalho de Melo 
17147c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, first loss event detected, creating history\n", dccp_role(sk), sk);
17157c657876SArnaldo Carvalho de Melo 			for (i = 0; i <= TFRC_RECV_IVAL_F_LENGTH; ++i) {
17167c657876SArnaldo Carvalho de Melo 				li_entry = ccid3_loss_interval_hist_entry_new(SLAB_ATOMIC);
17177c657876SArnaldo Carvalho de Melo 				if (li_entry == NULL) {
17187c657876SArnaldo Carvalho de Melo 					ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
17197c657876SArnaldo Carvalho de Melo 					ccid3_pr_debug("%s, sk=%p, not enough mem for creating history\n",
17207c657876SArnaldo Carvalho de Melo 						       dccp_role(sk), sk);
17217c657876SArnaldo Carvalho de Melo 					return;
17227c657876SArnaldo Carvalho de Melo 				}
17237c657876SArnaldo Carvalho de Melo 				if (li_tail == NULL)
17247c657876SArnaldo Carvalho de Melo 					li_tail = li_entry;
17257c657876SArnaldo Carvalho de Melo 				list_add(&li_entry->ccid3lih_node, &hcrx->ccid3hcrx_loss_interval_hist);
17267c657876SArnaldo Carvalho de Melo 			}
17277c657876SArnaldo Carvalho de Melo 
17287c657876SArnaldo Carvalho de Melo 			li_entry->ccid3lih_seqno     = seq_loss;
17297c657876SArnaldo Carvalho de Melo 			li_entry->ccid3lih_win_count = win_loss;
17307c657876SArnaldo Carvalho de Melo 
17317c657876SArnaldo Carvalho de Melo 			li_tail->ccid3lih_interval   = ccid3_hc_rx_calc_first_li(sk);
17327c657876SArnaldo Carvalho de Melo 		}
17337c657876SArnaldo Carvalho de Melo 	}
17347c657876SArnaldo Carvalho de Melo 	/* FIXME: find end of interval */
17357c657876SArnaldo Carvalho de Melo }
17367c657876SArnaldo Carvalho de Melo 
17377c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_detect_loss(struct sock *sk)
17387c657876SArnaldo Carvalho de Melo {
17397c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
17407c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
17418c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *packet;
17428c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *a_loss = NULL;
17438c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *b_loss = NULL;
17447c657876SArnaldo Carvalho de Melo 	u64 seq_loss = DCCP_MAX_SEQNO + 1;
17457c657876SArnaldo Carvalho de Melo 	u8 win_loss = 0;
17467c657876SArnaldo Carvalho de Melo 	u8 num_later = TFRC_RECV_NUM_LATE_LOSS;
17477c657876SArnaldo Carvalho de Melo 
17488c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
17498c60f3faSArnaldo Carvalho de Melo 				 dccphrx_node) {
17507c657876SArnaldo Carvalho de Melo 		if (num_later == 0) {
17517c657876SArnaldo Carvalho de Melo 			b_loss = entry;
17527c657876SArnaldo Carvalho de Melo 			break;
17538c60f3faSArnaldo Carvalho de Melo 		} else if (dccp_rx_hist_entry_data_packet(entry))
17547c657876SArnaldo Carvalho de Melo 			--num_later;
17557c657876SArnaldo Carvalho de Melo 	}
17567c657876SArnaldo Carvalho de Melo 
17577c657876SArnaldo Carvalho de Melo 	if (b_loss == NULL)
17587c657876SArnaldo Carvalho de Melo 		goto out_update_li;
17597c657876SArnaldo Carvalho de Melo 
17607c657876SArnaldo Carvalho de Melo 	num_later = 1;
1761757f612eSArnaldo Carvalho de Melo 
17628c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
17638c60f3faSArnaldo Carvalho de Melo 					  dccphrx_node) {
17647c657876SArnaldo Carvalho de Melo 		if (num_later == 0) {
17657c657876SArnaldo Carvalho de Melo 			a_loss = entry;
17667c657876SArnaldo Carvalho de Melo 			break;
17678c60f3faSArnaldo Carvalho de Melo 		} else if (dccp_rx_hist_entry_data_packet(entry))
17687c657876SArnaldo Carvalho de Melo 			--num_later;
17697c657876SArnaldo Carvalho de Melo 	}
17707c657876SArnaldo Carvalho de Melo 
17717c657876SArnaldo Carvalho de Melo 	if (a_loss == NULL) {
17727c657876SArnaldo Carvalho de Melo 		if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
17737c657876SArnaldo Carvalho de Melo 			/* no loss event have occured yet */
17747c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, TODO: find a lost data "
17757c657876SArnaldo Carvalho de Melo 					"packet by comparing to initial seqno\n",
17767c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
17777c657876SArnaldo Carvalho de Melo 			goto out_update_li;
17787c657876SArnaldo Carvalho de Melo 		} else {
17797c657876SArnaldo Carvalho de Melo 			pr_info("%s: %s, sk=%p, ERROR! Less than 4 data packets in history",
17807c657876SArnaldo Carvalho de Melo 				__FUNCTION__, dccp_role(sk), sk);
17817c657876SArnaldo Carvalho de Melo 			return;
17827c657876SArnaldo Carvalho de Melo 		}
17837c657876SArnaldo Carvalho de Melo 	}
17847c657876SArnaldo Carvalho de Melo 
17857c657876SArnaldo Carvalho de Melo 	/* Locate a lost data packet */
17867c657876SArnaldo Carvalho de Melo 	entry = packet = b_loss;
17878c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
17888c60f3faSArnaldo Carvalho de Melo 					  dccphrx_node) {
17898c60f3faSArnaldo Carvalho de Melo 		u64 delta = dccp_delta_seqno(entry->dccphrx_seqno,
17908c60f3faSArnaldo Carvalho de Melo 					     packet->dccphrx_seqno);
17917c657876SArnaldo Carvalho de Melo 
17927c657876SArnaldo Carvalho de Melo 		if (delta != 0) {
17938c60f3faSArnaldo Carvalho de Melo 			if (dccp_rx_hist_entry_data_packet(packet))
17947c657876SArnaldo Carvalho de Melo 				--delta;
17957c657876SArnaldo Carvalho de Melo 			/*
17967c657876SArnaldo Carvalho de Melo 			 * FIXME: check this, probably this % usage is because
17977c657876SArnaldo Carvalho de Melo 			 * in earlier drafts the ndp count was just 8 bits
17987c657876SArnaldo Carvalho de Melo 			 * long, but now it cam be up to 24 bits long.
17997c657876SArnaldo Carvalho de Melo 			 */
18007c657876SArnaldo Carvalho de Melo #if 0
18017c657876SArnaldo Carvalho de Melo 			if (delta % DCCP_NDP_LIMIT !=
18028c60f3faSArnaldo Carvalho de Melo 			    (packet->dccphrx_ndp -
18038c60f3faSArnaldo Carvalho de Melo 			     entry->dccphrx_ndp) % DCCP_NDP_LIMIT)
18047c657876SArnaldo Carvalho de Melo #endif
18058c60f3faSArnaldo Carvalho de Melo 			if (delta !=
18068c60f3faSArnaldo Carvalho de Melo 			     packet->dccphrx_ndp - entry->dccphrx_ndp) {
18078c60f3faSArnaldo Carvalho de Melo 				seq_loss = entry->dccphrx_seqno;
18087c657876SArnaldo Carvalho de Melo 				dccp_inc_seqno(&seq_loss);
18097c657876SArnaldo Carvalho de Melo 			}
18107c657876SArnaldo Carvalho de Melo 		}
18117c657876SArnaldo Carvalho de Melo 		packet = entry;
18127c657876SArnaldo Carvalho de Melo 		if (packet == a_loss)
18137c657876SArnaldo Carvalho de Melo 			break;
18147c657876SArnaldo Carvalho de Melo 	}
18157c657876SArnaldo Carvalho de Melo 
18167c657876SArnaldo Carvalho de Melo 	if (seq_loss != DCCP_MAX_SEQNO + 1)
1817c1734376SArnaldo Carvalho de Melo 		win_loss = a_loss->dccphrx_ccval;
18187c657876SArnaldo Carvalho de Melo 
18197c657876SArnaldo Carvalho de Melo out_update_li:
18207c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
18217c657876SArnaldo Carvalho de Melo }
18227c657876SArnaldo Carvalho de Melo 
18237c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_i_mean(struct sock *sk)
18247c657876SArnaldo Carvalho de Melo {
18257c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
18267c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
18277c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *li_entry, *li_next;
18287c657876SArnaldo Carvalho de Melo 	int i = 0;
18297c657876SArnaldo Carvalho de Melo 	u32 i_tot;
18307c657876SArnaldo Carvalho de Melo 	u32 i_tot0 = 0;
18317c657876SArnaldo Carvalho de Melo 	u32 i_tot1 = 0;
18327c657876SArnaldo Carvalho de Melo 	u32 w_tot  = 0;
18337c657876SArnaldo Carvalho de Melo 
18347c657876SArnaldo Carvalho de Melo 	list_for_each_entry_safe(li_entry, li_next, &hcrx->ccid3hcrx_loss_interval_hist, ccid3lih_node) {
18357c657876SArnaldo Carvalho de Melo 		if (i < TFRC_RECV_IVAL_F_LENGTH) {
18367c657876SArnaldo Carvalho de Melo 			i_tot0 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i];
18377c657876SArnaldo Carvalho de Melo 			w_tot  += ccid3_hc_rx_w[i];
18387c657876SArnaldo Carvalho de Melo 		}
18397c657876SArnaldo Carvalho de Melo 
18407c657876SArnaldo Carvalho de Melo 		if (i != 0)
18417c657876SArnaldo Carvalho de Melo 			i_tot1 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i - 1];
18427c657876SArnaldo Carvalho de Melo 
18437c657876SArnaldo Carvalho de Melo 		if (++i > TFRC_RECV_IVAL_F_LENGTH)
18447c657876SArnaldo Carvalho de Melo 			break;
18457c657876SArnaldo Carvalho de Melo 	}
18467c657876SArnaldo Carvalho de Melo 
18477c657876SArnaldo Carvalho de Melo 	if (i != TFRC_RECV_IVAL_F_LENGTH) {
18487c657876SArnaldo Carvalho de Melo 		pr_info("%s: %s, sk=%p, ERROR! Missing entry in interval history!\n",
18497c657876SArnaldo Carvalho de Melo 			__FUNCTION__, dccp_role(sk), sk);
18507c657876SArnaldo Carvalho de Melo 		return 0;
18517c657876SArnaldo Carvalho de Melo 	}
18527c657876SArnaldo Carvalho de Melo 
18537c657876SArnaldo Carvalho de Melo 	i_tot = max(i_tot0, i_tot1);
18547c657876SArnaldo Carvalho de Melo 
18557c657876SArnaldo Carvalho de Melo 	/* FIXME: Why do we do this? -Ian McDonald */
18567c657876SArnaldo Carvalho de Melo 	if (i_tot * 4 < w_tot)
18577c657876SArnaldo Carvalho de Melo 		i_tot = w_tot * 4;
18587c657876SArnaldo Carvalho de Melo 
18597c657876SArnaldo Carvalho de Melo 	return i_tot * 4 / w_tot;
18607c657876SArnaldo Carvalho de Melo }
18617c657876SArnaldo Carvalho de Melo 
18627c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
18637c657876SArnaldo Carvalho de Melo {
18647c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
18657c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
18664fded33bSArnaldo Carvalho de Melo 	const struct dccp_options_received *opt_recv;
18678c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *packet;
18687c657876SArnaldo Carvalho de Melo 	struct timeval now;
18694fded33bSArnaldo Carvalho de Melo 	u32 now_usecs;
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 
18844fded33bSArnaldo Carvalho de Melo 	opt_recv = &dp->dccps_options_received;
18854fded33bSArnaldo Carvalho de Melo 
18867c657876SArnaldo Carvalho de Melo 	switch (DCCP_SKB_CB(skb)->dccpd_type) {
18877c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_ACK:
18887c657876SArnaldo Carvalho de Melo 		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
18897c657876SArnaldo Carvalho de Melo 			return;
18907c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_DATAACK:
18914fded33bSArnaldo Carvalho de Melo 		if (opt_recv->dccpor_timestamp_echo == 0)
18927c657876SArnaldo Carvalho de Melo 			break;
18937c657876SArnaldo Carvalho de Melo 		p_prev = hcrx->ccid3hcrx_rtt;
18947c657876SArnaldo Carvalho de Melo 		do_gettimeofday(&now);
18954fded33bSArnaldo Carvalho de Melo 		now_usecs = now.tv_sec * USEC_PER_SEC + now.tv_usec;
18964fded33bSArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_rtt = now_usecs -
18974fded33bSArnaldo Carvalho de Melo 				     (opt_recv->dccpor_timestamp_echo -
18984fded33bSArnaldo Carvalho de Melo 				      opt_recv->dccpor_elapsed_time) * 10;
18997c657876SArnaldo Carvalho de Melo 		if (p_prev != hcrx->ccid3hcrx_rtt)
19004fded33bSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
19014fded33bSArnaldo Carvalho de Melo 				       dccp_role(sk), hcrx->ccid3hcrx_rtt,
19024fded33bSArnaldo Carvalho de Melo 				       opt_recv->dccpor_elapsed_time);
19037c657876SArnaldo Carvalho de Melo 		break;
19047c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_DATA:
19057c657876SArnaldo Carvalho de Melo 		break;
19067c657876SArnaldo Carvalho de Melo 	default:
19077c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n",
19087c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
19097c657876SArnaldo Carvalho de Melo 			       dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
19107c657876SArnaldo Carvalho de Melo 		return;
19117c657876SArnaldo Carvalho de Melo 	}
19127c657876SArnaldo Carvalho de Melo 
19134fded33bSArnaldo Carvalho de Melo 	packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->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) {
19384fded33bSArnaldo Carvalho de Melo 			if (now_delta(hcrx->ccid3hcrx_tstamp_last_ack) >=
19394fded33bSArnaldo Carvalho de Melo 			    hcrx->ccid3hcrx_rtt) {
19404fded33bSArnaldo Carvalho de Melo 				do_gettimeofday(&hcrx->ccid3hcrx_tstamp_last_ack);
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 */
19544fded33bSArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
19554fded33bSArnaldo Carvalho de Melo 		       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
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);
19934fded33bSArnaldo Carvalho de Melo 	/*
19944fded33bSArnaldo Carvalho de Melo 	 * XXX this seems to be paranoid, need to think more about this, for
19954fded33bSArnaldo Carvalho de Melo 	 * now start with something different than zero. -acme
19964fded33bSArnaldo Carvalho de Melo 	 */
19974fded33bSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_rtt = USEC_PER_SEC / 5;
19987c657876SArnaldo Carvalho de Melo 	return 0;
19997c657876SArnaldo Carvalho de Melo }
20007c657876SArnaldo Carvalho de Melo 
20017c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_exit(struct sock *sk)
20027c657876SArnaldo Carvalho de Melo {
20037c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
20047c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
20057c657876SArnaldo Carvalho de Melo 
20067c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
20077c657876SArnaldo Carvalho de Melo 
20087c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
20097c657876SArnaldo Carvalho de Melo 		return;
20107c657876SArnaldo Carvalho de Melo 
20117c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
20127c657876SArnaldo Carvalho de Melo 
20137c657876SArnaldo Carvalho de Melo 	/* Empty packet history */
20148c60f3faSArnaldo Carvalho de Melo 	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
20157c657876SArnaldo Carvalho de Melo 
20167c657876SArnaldo Carvalho de Melo 	/* Empty loss interval history */
20177c657876SArnaldo Carvalho de Melo 	ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
20187c657876SArnaldo Carvalho de Melo 
20197c657876SArnaldo Carvalho de Melo 	kfree(dp->dccps_hc_rx_ccid_private);
20207c657876SArnaldo Carvalho de Melo 	dp->dccps_hc_rx_ccid_private = NULL;
20217c657876SArnaldo Carvalho de Melo }
20227c657876SArnaldo Carvalho de Melo 
20232babe1f6SArnaldo Carvalho de Melo static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
20242babe1f6SArnaldo Carvalho de Melo {
20252babe1f6SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
20262babe1f6SArnaldo Carvalho de Melo 	const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
20272babe1f6SArnaldo Carvalho de Melo 
20282babe1f6SArnaldo Carvalho de Melo 	if (hcrx == NULL)
20292babe1f6SArnaldo Carvalho de Melo 		return;
20302babe1f6SArnaldo Carvalho de Melo 
20312babe1f6SArnaldo Carvalho de Melo 	info->tcpi_ca_state	= hcrx->ccid3hcrx_state;
20322babe1f6SArnaldo Carvalho de Melo 	info->tcpi_options	|= TCPI_OPT_TIMESTAMPS;
20332babe1f6SArnaldo Carvalho de Melo 	info->tcpi_rcv_rtt	= hcrx->ccid3hcrx_rtt;
20342babe1f6SArnaldo Carvalho de Melo }
20352babe1f6SArnaldo Carvalho de Melo 
20362babe1f6SArnaldo Carvalho de Melo static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
20372babe1f6SArnaldo Carvalho de Melo {
20382babe1f6SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
20392babe1f6SArnaldo Carvalho de Melo 	const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
20402babe1f6SArnaldo Carvalho de Melo 
20412babe1f6SArnaldo Carvalho de Melo 	if (hctx == NULL)
20422babe1f6SArnaldo Carvalho de Melo 		return;
20432babe1f6SArnaldo Carvalho de Melo 
20442babe1f6SArnaldo Carvalho de Melo 	info->tcpi_rto = hctx->ccid3hctx_t_rto;
20452babe1f6SArnaldo Carvalho de Melo 	info->tcpi_rtt = hctx->ccid3hctx_rtt;
20462babe1f6SArnaldo Carvalho de Melo }
20472babe1f6SArnaldo Carvalho de Melo 
20487c657876SArnaldo Carvalho de Melo static struct ccid ccid3 = {
20497c657876SArnaldo Carvalho de Melo 	.ccid_id		   = 3,
20507c657876SArnaldo Carvalho de Melo 	.ccid_name		   = "ccid3",
20517c657876SArnaldo Carvalho de Melo 	.ccid_owner		   = THIS_MODULE,
20527c657876SArnaldo Carvalho de Melo 	.ccid_init		   = ccid3_init,
20537c657876SArnaldo Carvalho de Melo 	.ccid_exit		   = ccid3_exit,
20547c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
20557c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,
20567c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_send_packet	   = ccid3_hc_tx_send_packet,
20577c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_packet_sent	   = ccid3_hc_tx_packet_sent,
20587c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_packet_recv	   = ccid3_hc_tx_packet_recv,
20597c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
20607c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_parse_options  = ccid3_hc_tx_parse_options,
20617c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_init	   = ccid3_hc_rx_init,
20627c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_exit	   = ccid3_hc_rx_exit,
20637c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
20647c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_packet_recv	   = ccid3_hc_rx_packet_recv,
20652babe1f6SArnaldo Carvalho de Melo 	.ccid_hc_rx_get_info	   = ccid3_hc_rx_get_info,
20662babe1f6SArnaldo Carvalho de Melo 	.ccid_hc_tx_get_info	   = ccid3_hc_tx_get_info,
20677c657876SArnaldo Carvalho de Melo };
20687c657876SArnaldo Carvalho de Melo 
20697c657876SArnaldo Carvalho de Melo module_param(ccid3_debug, int, 0444);
20707c657876SArnaldo Carvalho de Melo MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
20717c657876SArnaldo Carvalho de Melo 
20727c657876SArnaldo Carvalho de Melo static __init int ccid3_module_init(void)
20737c657876SArnaldo Carvalho de Melo {
20748c60f3faSArnaldo Carvalho de Melo 	int rc = -ENOBUFS;
20757c657876SArnaldo Carvalho de Melo 
20768c60f3faSArnaldo Carvalho de Melo 	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
20778c60f3faSArnaldo Carvalho de Melo 	if (ccid3_rx_hist == NULL)
20787c657876SArnaldo Carvalho de Melo 		goto out;
20797c657876SArnaldo Carvalho de Melo 
20808c60f3faSArnaldo Carvalho de Melo 	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
20818c60f3faSArnaldo Carvalho de Melo 	if (ccid3_tx_hist == NULL)
20828c60f3faSArnaldo Carvalho de Melo 		goto out_free_rx;
20837c657876SArnaldo Carvalho de Melo 
20848c60f3faSArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_slab = kmem_cache_create("li_hist_ccid3",
20858c60f3faSArnaldo Carvalho de Melo 				  sizeof(struct ccid3_loss_interval_hist_entry),
20868c60f3faSArnaldo Carvalho de Melo 							  0, SLAB_HWCACHE_ALIGN,
20878c60f3faSArnaldo Carvalho de Melo 							  NULL, NULL);
20887c657876SArnaldo Carvalho de Melo 	if (ccid3_loss_interval_hist_slab == NULL)
20898c60f3faSArnaldo Carvalho de Melo 		goto out_free_tx;
20907c657876SArnaldo Carvalho de Melo 
20917c657876SArnaldo Carvalho de Melo 	rc = ccid_register(&ccid3);
20927c657876SArnaldo Carvalho de Melo 	if (rc != 0)
20937c657876SArnaldo Carvalho de Melo 		goto out_free_loss_interval_history;
20947c657876SArnaldo Carvalho de Melo out:
20957c657876SArnaldo Carvalho de Melo 	return rc;
20968c60f3faSArnaldo Carvalho de Melo 
20977c657876SArnaldo Carvalho de Melo out_free_loss_interval_history:
20987c657876SArnaldo Carvalho de Melo 	kmem_cache_destroy(ccid3_loss_interval_hist_slab);
20997c657876SArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_slab = NULL;
21008c60f3faSArnaldo Carvalho de Melo out_free_tx:
21018c60f3faSArnaldo Carvalho de Melo 	dccp_tx_hist_delete(ccid3_tx_hist);
21028c60f3faSArnaldo Carvalho de Melo 	ccid3_tx_hist = NULL;
21038c60f3faSArnaldo Carvalho de Melo out_free_rx:
21048c60f3faSArnaldo Carvalho de Melo 	dccp_rx_hist_delete(ccid3_rx_hist);
21058c60f3faSArnaldo Carvalho de Melo 	ccid3_rx_hist = NULL;
21067c657876SArnaldo Carvalho de Melo 	goto out;
21077c657876SArnaldo Carvalho de Melo }
21087c657876SArnaldo Carvalho de Melo module_init(ccid3_module_init);
21097c657876SArnaldo Carvalho de Melo 
21107c657876SArnaldo Carvalho de Melo static __exit void ccid3_module_exit(void)
21117c657876SArnaldo Carvalho de Melo {
2112725ba8eeSArnaldo Carvalho de Melo #ifdef CONFIG_IP_DCCP_UNLOAD_HACK
2113725ba8eeSArnaldo Carvalho de Melo 	/*
2114725ba8eeSArnaldo Carvalho de Melo 	 * Hack to use while developing, so that we get rid of the control
2115725ba8eeSArnaldo Carvalho de Melo 	 * sock, that is what keeps a refcount on dccp.ko -acme
2116725ba8eeSArnaldo Carvalho de Melo 	 */
2117725ba8eeSArnaldo Carvalho de Melo 	extern void dccp_ctl_sock_exit(void);
2118725ba8eeSArnaldo Carvalho de Melo 
2119725ba8eeSArnaldo Carvalho de Melo 	dccp_ctl_sock_exit();
2120725ba8eeSArnaldo Carvalho de Melo #endif
21217c657876SArnaldo Carvalho de Melo 	ccid_unregister(&ccid3);
21227c657876SArnaldo Carvalho de Melo 
21238c60f3faSArnaldo Carvalho de Melo 	if (ccid3_tx_hist != NULL) {
21248c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_delete(ccid3_tx_hist);
21258c60f3faSArnaldo Carvalho de Melo 		ccid3_tx_hist = NULL;
21267c657876SArnaldo Carvalho de Melo 	}
21278c60f3faSArnaldo Carvalho de Melo 	if (ccid3_rx_hist != NULL) {
21288c60f3faSArnaldo Carvalho de Melo 		dccp_rx_hist_delete(ccid3_rx_hist);
21298c60f3faSArnaldo Carvalho de Melo 		ccid3_rx_hist = NULL;
21307c657876SArnaldo Carvalho de Melo 	}
21317c657876SArnaldo Carvalho de Melo 	if (ccid3_loss_interval_hist_slab != NULL) {
21327c657876SArnaldo Carvalho de Melo 		kmem_cache_destroy(ccid3_loss_interval_hist_slab);
21337c657876SArnaldo Carvalho de Melo 		ccid3_loss_interval_hist_slab = NULL;
21347c657876SArnaldo Carvalho de Melo 	}
21357c657876SArnaldo Carvalho de Melo }
21367c657876SArnaldo Carvalho de Melo module_exit(ccid3_module_exit);
21377c657876SArnaldo Carvalho de Melo 
21387c657876SArnaldo Carvalho de Melo MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz> & Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
21397c657876SArnaldo Carvalho de Melo MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
21407c657876SArnaldo Carvalho de Melo MODULE_LICENSE("GPL");
21417c657876SArnaldo Carvalho de Melo MODULE_ALIAS("net-dccp-ccid-3");
2142