xref: /openbmc/linux/net/dccp/ccids/ccid3.c (revision b6ee3d4a)
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 
88ba89966cSEric Dumazet static kmem_cache_t *ccid3_loss_interval_hist_slab __read_mostly;
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 
1451f2333aeSArnaldo Carvalho de Melo static inline void ccid3_hc_tx_set_state(struct sock *sk,
1461f2333aeSArnaldo Carvalho de Melo 					 enum ccid3_hc_tx_states state)
1477c657876SArnaldo Carvalho de Melo {
1487c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
1497c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
1507c657876SArnaldo Carvalho de Melo 	enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
1517c657876SArnaldo Carvalho de Melo 
1527c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
1531f2333aeSArnaldo Carvalho de Melo 		       dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
1541f2333aeSArnaldo Carvalho de Melo 		       ccid3_tx_state_name(state));
1557c657876SArnaldo Carvalho de Melo 	WARN_ON(state == oldstate);
1567c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_state = state;
1577c657876SArnaldo Carvalho de Melo }
1587c657876SArnaldo Carvalho de Melo 
1597c657876SArnaldo Carvalho de Melo #define CALCX_ARRSIZE 500
1607c657876SArnaldo Carvalho de Melo 
1617c657876SArnaldo Carvalho de Melo #define CALCX_SPLIT 50000
1627c657876SArnaldo Carvalho de Melo /* equivalent to 0.05 */
1637c657876SArnaldo Carvalho de Melo 
1647c657876SArnaldo Carvalho de Melo static const u32 calcx_lookup[CALCX_ARRSIZE][2] = {
1657c657876SArnaldo Carvalho de Melo 	{ 37172 , 8172 },
1667c657876SArnaldo Carvalho de Melo 	{ 53499 , 11567 },
1677c657876SArnaldo Carvalho de Melo 	{ 66664 , 14180 },
1687c657876SArnaldo Carvalho de Melo 	{ 78298 , 16388 },
1697c657876SArnaldo Carvalho de Melo 	{ 89021 , 18339 },
1707c657876SArnaldo Carvalho de Melo 	{ 99147 , 20108 },
1717c657876SArnaldo Carvalho de Melo 	{ 108858 , 21738 },
1727c657876SArnaldo Carvalho de Melo 	{ 118273 , 23260 },
1737c657876SArnaldo Carvalho de Melo 	{ 127474 , 24693 },
1747c657876SArnaldo Carvalho de Melo 	{ 136520 , 26052 },
1757c657876SArnaldo Carvalho de Melo 	{ 145456 , 27348 },
1767c657876SArnaldo Carvalho de Melo 	{ 154316 , 28589 },
1777c657876SArnaldo Carvalho de Melo 	{ 163130 , 29783 },
1787c657876SArnaldo Carvalho de Melo 	{ 171919 , 30935 },
1797c657876SArnaldo Carvalho de Melo 	{ 180704 , 32049 },
1807c657876SArnaldo Carvalho de Melo 	{ 189502 , 33130 },
1817c657876SArnaldo Carvalho de Melo 	{ 198328 , 34180 },
1827c657876SArnaldo Carvalho de Melo 	{ 207194 , 35202 },
1837c657876SArnaldo Carvalho de Melo 	{ 216114 , 36198 },
1847c657876SArnaldo Carvalho de Melo 	{ 225097 , 37172 },
1857c657876SArnaldo Carvalho de Melo 	{ 234153 , 38123 },
1867c657876SArnaldo Carvalho de Melo 	{ 243294 , 39055 },
1877c657876SArnaldo Carvalho de Melo 	{ 252527 , 39968 },
1887c657876SArnaldo Carvalho de Melo 	{ 261861 , 40864 },
1897c657876SArnaldo Carvalho de Melo 	{ 271305 , 41743 },
1907c657876SArnaldo Carvalho de Melo 	{ 280866 , 42607 },
1917c657876SArnaldo Carvalho de Melo 	{ 290553 , 43457 },
1927c657876SArnaldo Carvalho de Melo 	{ 300372 , 44293 },
1937c657876SArnaldo Carvalho de Melo 	{ 310333 , 45117 },
1947c657876SArnaldo Carvalho de Melo 	{ 320441 , 45929 },
1957c657876SArnaldo Carvalho de Melo 	{ 330705 , 46729 },
1967c657876SArnaldo Carvalho de Melo 	{ 341131 , 47518 },
1977c657876SArnaldo Carvalho de Melo 	{ 351728 , 48297 },
1987c657876SArnaldo Carvalho de Melo 	{ 362501 , 49066 },
1997c657876SArnaldo Carvalho de Melo 	{ 373460 , 49826 },
2007c657876SArnaldo Carvalho de Melo 	{ 384609 , 50577 },
2017c657876SArnaldo Carvalho de Melo 	{ 395958 , 51320 },
2027c657876SArnaldo Carvalho de Melo 	{ 407513 , 52054 },
2037c657876SArnaldo Carvalho de Melo 	{ 419281 , 52780 },
2047c657876SArnaldo Carvalho de Melo 	{ 431270 , 53499 },
2057c657876SArnaldo Carvalho de Melo 	{ 443487 , 54211 },
2067c657876SArnaldo Carvalho de Melo 	{ 455940 , 54916 },
2077c657876SArnaldo Carvalho de Melo 	{ 468635 , 55614 },
2087c657876SArnaldo Carvalho de Melo 	{ 481581 , 56306 },
2097c657876SArnaldo Carvalho de Melo 	{ 494785 , 56991 },
2107c657876SArnaldo Carvalho de Melo 	{ 508254 , 57671 },
2117c657876SArnaldo Carvalho de Melo 	{ 521996 , 58345 },
2127c657876SArnaldo Carvalho de Melo 	{ 536019 , 59014 },
2137c657876SArnaldo Carvalho de Melo 	{ 550331 , 59677 },
2147c657876SArnaldo Carvalho de Melo 	{ 564939 , 60335 },
2157c657876SArnaldo Carvalho de Melo 	{ 579851 , 60988 },
2167c657876SArnaldo Carvalho de Melo 	{ 595075 , 61636 },
2177c657876SArnaldo Carvalho de Melo 	{ 610619 , 62279 },
2187c657876SArnaldo Carvalho de Melo 	{ 626491 , 62918 },
2197c657876SArnaldo Carvalho de Melo 	{ 642700 , 63553 },
2207c657876SArnaldo Carvalho de Melo 	{ 659253 , 64183 },
2217c657876SArnaldo Carvalho de Melo 	{ 676158 , 64809 },
2227c657876SArnaldo Carvalho de Melo 	{ 693424 , 65431 },
2237c657876SArnaldo Carvalho de Melo 	{ 711060 , 66050 },
2247c657876SArnaldo Carvalho de Melo 	{ 729073 , 66664 },
2257c657876SArnaldo Carvalho de Melo 	{ 747472 , 67275 },
2267c657876SArnaldo Carvalho de Melo 	{ 766266 , 67882 },
2277c657876SArnaldo Carvalho de Melo 	{ 785464 , 68486 },
2287c657876SArnaldo Carvalho de Melo 	{ 805073 , 69087 },
2297c657876SArnaldo Carvalho de Melo 	{ 825103 , 69684 },
2307c657876SArnaldo Carvalho de Melo 	{ 845562 , 70278 },
2317c657876SArnaldo Carvalho de Melo 	{ 866460 , 70868 },
2327c657876SArnaldo Carvalho de Melo 	{ 887805 , 71456 },
2337c657876SArnaldo Carvalho de Melo 	{ 909606 , 72041 },
2347c657876SArnaldo Carvalho de Melo 	{ 931873 , 72623 },
2357c657876SArnaldo Carvalho de Melo 	{ 954614 , 73202 },
2367c657876SArnaldo Carvalho de Melo 	{ 977839 , 73778 },
2377c657876SArnaldo Carvalho de Melo 	{ 1001557 , 74352 },
2387c657876SArnaldo Carvalho de Melo 	{ 1025777 , 74923 },
2397c657876SArnaldo Carvalho de Melo 	{ 1050508 , 75492 },
2407c657876SArnaldo Carvalho de Melo 	{ 1075761 , 76058 },
2417c657876SArnaldo Carvalho de Melo 	{ 1101544 , 76621 },
2427c657876SArnaldo Carvalho de Melo 	{ 1127867 , 77183 },
2437c657876SArnaldo Carvalho de Melo 	{ 1154739 , 77741 },
2447c657876SArnaldo Carvalho de Melo 	{ 1182172 , 78298 },
2457c657876SArnaldo Carvalho de Melo 	{ 1210173 , 78852 },
2467c657876SArnaldo Carvalho de Melo 	{ 1238753 , 79405 },
2477c657876SArnaldo Carvalho de Melo 	{ 1267922 , 79955 },
2487c657876SArnaldo Carvalho de Melo 	{ 1297689 , 80503 },
2497c657876SArnaldo Carvalho de Melo 	{ 1328066 , 81049 },
2507c657876SArnaldo Carvalho de Melo 	{ 1359060 , 81593 },
2517c657876SArnaldo Carvalho de Melo 	{ 1390684 , 82135 },
2527c657876SArnaldo Carvalho de Melo 	{ 1422947 , 82675 },
2537c657876SArnaldo Carvalho de Melo 	{ 1455859 , 83213 },
2547c657876SArnaldo Carvalho de Melo 	{ 1489430 , 83750 },
2557c657876SArnaldo Carvalho de Melo 	{ 1523671 , 84284 },
2567c657876SArnaldo Carvalho de Melo 	{ 1558593 , 84817 },
2577c657876SArnaldo Carvalho de Melo 	{ 1594205 , 85348 },
2587c657876SArnaldo Carvalho de Melo 	{ 1630518 , 85878 },
2597c657876SArnaldo Carvalho de Melo 	{ 1667543 , 86406 },
2607c657876SArnaldo Carvalho de Melo 	{ 1705290 , 86932 },
2617c657876SArnaldo Carvalho de Melo 	{ 1743770 , 87457 },
2627c657876SArnaldo Carvalho de Melo 	{ 1782994 , 87980 },
2637c657876SArnaldo Carvalho de Melo 	{ 1822973 , 88501 },
2647c657876SArnaldo Carvalho de Melo 	{ 1863717 , 89021 },
2657c657876SArnaldo Carvalho de Melo 	{ 1905237 , 89540 },
2667c657876SArnaldo Carvalho de Melo 	{ 1947545 , 90057 },
2677c657876SArnaldo Carvalho de Melo 	{ 1990650 , 90573 },
2687c657876SArnaldo Carvalho de Melo 	{ 2034566 , 91087 },
2697c657876SArnaldo Carvalho de Melo 	{ 2079301 , 91600 },
2707c657876SArnaldo Carvalho de Melo 	{ 2124869 , 92111 },
2717c657876SArnaldo Carvalho de Melo 	{ 2171279 , 92622 },
2727c657876SArnaldo Carvalho de Melo 	{ 2218543 , 93131 },
2737c657876SArnaldo Carvalho de Melo 	{ 2266673 , 93639 },
2747c657876SArnaldo Carvalho de Melo 	{ 2315680 , 94145 },
2757c657876SArnaldo Carvalho de Melo 	{ 2365575 , 94650 },
2767c657876SArnaldo Carvalho de Melo 	{ 2416371 , 95154 },
2777c657876SArnaldo Carvalho de Melo 	{ 2468077 , 95657 },
2787c657876SArnaldo Carvalho de Melo 	{ 2520707 , 96159 },
2797c657876SArnaldo Carvalho de Melo 	{ 2574271 , 96660 },
2807c657876SArnaldo Carvalho de Melo 	{ 2628782 , 97159 },
2817c657876SArnaldo Carvalho de Melo 	{ 2684250 , 97658 },
2827c657876SArnaldo Carvalho de Melo 	{ 2740689 , 98155 },
2837c657876SArnaldo Carvalho de Melo 	{ 2798110 , 98651 },
2847c657876SArnaldo Carvalho de Melo 	{ 2856524 , 99147 },
2857c657876SArnaldo Carvalho de Melo 	{ 2915944 , 99641 },
2867c657876SArnaldo Carvalho de Melo 	{ 2976382 , 100134 },
2877c657876SArnaldo Carvalho de Melo 	{ 3037850 , 100626 },
2887c657876SArnaldo Carvalho de Melo 	{ 3100360 , 101117 },
2897c657876SArnaldo Carvalho de Melo 	{ 3163924 , 101608 },
2907c657876SArnaldo Carvalho de Melo 	{ 3228554 , 102097 },
2917c657876SArnaldo Carvalho de Melo 	{ 3294263 , 102586 },
2927c657876SArnaldo Carvalho de Melo 	{ 3361063 , 103073 },
2937c657876SArnaldo Carvalho de Melo 	{ 3428966 , 103560 },
2947c657876SArnaldo Carvalho de Melo 	{ 3497984 , 104045 },
2957c657876SArnaldo Carvalho de Melo 	{ 3568131 , 104530 },
2967c657876SArnaldo Carvalho de Melo 	{ 3639419 , 105014 },
2977c657876SArnaldo Carvalho de Melo 	{ 3711860 , 105498 },
2987c657876SArnaldo Carvalho de Melo 	{ 3785467 , 105980 },
2997c657876SArnaldo Carvalho de Melo 	{ 3860253 , 106462 },
3007c657876SArnaldo Carvalho de Melo 	{ 3936229 , 106942 },
3017c657876SArnaldo Carvalho de Melo 	{ 4013410 , 107422 },
3027c657876SArnaldo Carvalho de Melo 	{ 4091808 , 107902 },
3037c657876SArnaldo Carvalho de Melo 	{ 4171435 , 108380 },
3047c657876SArnaldo Carvalho de Melo 	{ 4252306 , 108858 },
3057c657876SArnaldo Carvalho de Melo 	{ 4334431 , 109335 },
3067c657876SArnaldo Carvalho de Melo 	{ 4417825 , 109811 },
3077c657876SArnaldo Carvalho de Melo 	{ 4502501 , 110287 },
3087c657876SArnaldo Carvalho de Melo 	{ 4588472 , 110762 },
3097c657876SArnaldo Carvalho de Melo 	{ 4675750 , 111236 },
3107c657876SArnaldo Carvalho de Melo 	{ 4764349 , 111709 },
3117c657876SArnaldo Carvalho de Melo 	{ 4854283 , 112182 },
3127c657876SArnaldo Carvalho de Melo 	{ 4945564 , 112654 },
3137c657876SArnaldo Carvalho de Melo 	{ 5038206 , 113126 },
3147c657876SArnaldo Carvalho de Melo 	{ 5132223 , 113597 },
3157c657876SArnaldo Carvalho de Melo 	{ 5227627 , 114067 },
3167c657876SArnaldo Carvalho de Melo 	{ 5324432 , 114537 },
3177c657876SArnaldo Carvalho de Melo 	{ 5422652 , 115006 },
3187c657876SArnaldo Carvalho de Melo 	{ 5522299 , 115474 },
3197c657876SArnaldo Carvalho de Melo 	{ 5623389 , 115942 },
3207c657876SArnaldo Carvalho de Melo 	{ 5725934 , 116409 },
3217c657876SArnaldo Carvalho de Melo 	{ 5829948 , 116876 },
3227c657876SArnaldo Carvalho de Melo 	{ 5935446 , 117342 },
3237c657876SArnaldo Carvalho de Melo 	{ 6042439 , 117808 },
3247c657876SArnaldo Carvalho de Melo 	{ 6150943 , 118273 },
3257c657876SArnaldo Carvalho de Melo 	{ 6260972 , 118738 },
3267c657876SArnaldo Carvalho de Melo 	{ 6372538 , 119202 },
3277c657876SArnaldo Carvalho de Melo 	{ 6485657 , 119665 },
3287c657876SArnaldo Carvalho de Melo 	{ 6600342 , 120128 },
3297c657876SArnaldo Carvalho de Melo 	{ 6716607 , 120591 },
3307c657876SArnaldo Carvalho de Melo 	{ 6834467 , 121053 },
3317c657876SArnaldo Carvalho de Melo 	{ 6953935 , 121514 },
3327c657876SArnaldo Carvalho de Melo 	{ 7075025 , 121976 },
3337c657876SArnaldo Carvalho de Melo 	{ 7197752 , 122436 },
3347c657876SArnaldo Carvalho de Melo 	{ 7322131 , 122896 },
3357c657876SArnaldo Carvalho de Melo 	{ 7448175 , 123356 },
3367c657876SArnaldo Carvalho de Melo 	{ 7575898 , 123815 },
3377c657876SArnaldo Carvalho de Melo 	{ 7705316 , 124274 },
3387c657876SArnaldo Carvalho de Melo 	{ 7836442 , 124733 },
3397c657876SArnaldo Carvalho de Melo 	{ 7969291 , 125191 },
3407c657876SArnaldo Carvalho de Melo 	{ 8103877 , 125648 },
3417c657876SArnaldo Carvalho de Melo 	{ 8240216 , 126105 },
3427c657876SArnaldo Carvalho de Melo 	{ 8378321 , 126562 },
3437c657876SArnaldo Carvalho de Melo 	{ 8518208 , 127018 },
3447c657876SArnaldo Carvalho de Melo 	{ 8659890 , 127474 },
3457c657876SArnaldo Carvalho de Melo 	{ 8803384 , 127930 },
3467c657876SArnaldo Carvalho de Melo 	{ 8948702 , 128385 },
3477c657876SArnaldo Carvalho de Melo 	{ 9095861 , 128840 },
3487c657876SArnaldo Carvalho de Melo 	{ 9244875 , 129294 },
3497c657876SArnaldo Carvalho de Melo 	{ 9395760 , 129748 },
3507c657876SArnaldo Carvalho de Melo 	{ 9548529 , 130202 },
3517c657876SArnaldo Carvalho de Melo 	{ 9703198 , 130655 },
3527c657876SArnaldo Carvalho de Melo 	{ 9859782 , 131108 },
3537c657876SArnaldo Carvalho de Melo 	{ 10018296 , 131561 },
3547c657876SArnaldo Carvalho de Melo 	{ 10178755 , 132014 },
3557c657876SArnaldo Carvalho de Melo 	{ 10341174 , 132466 },
3567c657876SArnaldo Carvalho de Melo 	{ 10505569 , 132917 },
3577c657876SArnaldo Carvalho de Melo 	{ 10671954 , 133369 },
3587c657876SArnaldo Carvalho de Melo 	{ 10840345 , 133820 },
3597c657876SArnaldo Carvalho de Melo 	{ 11010757 , 134271 },
3607c657876SArnaldo Carvalho de Melo 	{ 11183206 , 134721 },
3617c657876SArnaldo Carvalho de Melo 	{ 11357706 , 135171 },
3627c657876SArnaldo Carvalho de Melo 	{ 11534274 , 135621 },
3637c657876SArnaldo Carvalho de Melo 	{ 11712924 , 136071 },
3647c657876SArnaldo Carvalho de Melo 	{ 11893673 , 136520 },
3657c657876SArnaldo Carvalho de Melo 	{ 12076536 , 136969 },
3667c657876SArnaldo Carvalho de Melo 	{ 12261527 , 137418 },
3677c657876SArnaldo Carvalho de Melo 	{ 12448664 , 137867 },
3687c657876SArnaldo Carvalho de Melo 	{ 12637961 , 138315 },
3697c657876SArnaldo Carvalho de Melo 	{ 12829435 , 138763 },
3707c657876SArnaldo Carvalho de Melo 	{ 13023101 , 139211 },
3717c657876SArnaldo Carvalho de Melo 	{ 13218974 , 139658 },
3727c657876SArnaldo Carvalho de Melo 	{ 13417071 , 140106 },
3737c657876SArnaldo Carvalho de Melo 	{ 13617407 , 140553 },
3747c657876SArnaldo Carvalho de Melo 	{ 13819999 , 140999 },
3757c657876SArnaldo Carvalho de Melo 	{ 14024862 , 141446 },
3767c657876SArnaldo Carvalho de Melo 	{ 14232012 , 141892 },
3777c657876SArnaldo Carvalho de Melo 	{ 14441465 , 142339 },
3787c657876SArnaldo Carvalho de Melo 	{ 14653238 , 142785 },
3797c657876SArnaldo Carvalho de Melo 	{ 14867346 , 143230 },
3807c657876SArnaldo Carvalho de Melo 	{ 15083805 , 143676 },
3817c657876SArnaldo Carvalho de Melo 	{ 15302632 , 144121 },
3827c657876SArnaldo Carvalho de Melo 	{ 15523842 , 144566 },
3837c657876SArnaldo Carvalho de Melo 	{ 15747453 , 145011 },
3847c657876SArnaldo Carvalho de Melo 	{ 15973479 , 145456 },
3857c657876SArnaldo Carvalho de Melo 	{ 16201939 , 145900 },
3867c657876SArnaldo Carvalho de Melo 	{ 16432847 , 146345 },
3877c657876SArnaldo Carvalho de Melo 	{ 16666221 , 146789 },
3887c657876SArnaldo Carvalho de Melo 	{ 16902076 , 147233 },
3897c657876SArnaldo Carvalho de Melo 	{ 17140429 , 147677 },
3907c657876SArnaldo Carvalho de Melo 	{ 17381297 , 148121 },
3917c657876SArnaldo Carvalho de Melo 	{ 17624696 , 148564 },
3927c657876SArnaldo Carvalho de Melo 	{ 17870643 , 149007 },
3937c657876SArnaldo Carvalho de Melo 	{ 18119154 , 149451 },
3947c657876SArnaldo Carvalho de Melo 	{ 18370247 , 149894 },
3957c657876SArnaldo Carvalho de Melo 	{ 18623936 , 150336 },
3967c657876SArnaldo Carvalho de Melo 	{ 18880241 , 150779 },
3977c657876SArnaldo Carvalho de Melo 	{ 19139176 , 151222 },
3987c657876SArnaldo Carvalho de Melo 	{ 19400759 , 151664 },
3997c657876SArnaldo Carvalho de Melo 	{ 19665007 , 152107 },
4007c657876SArnaldo Carvalho de Melo 	{ 19931936 , 152549 },
4017c657876SArnaldo Carvalho de Melo 	{ 20201564 , 152991 },
4027c657876SArnaldo Carvalho de Melo 	{ 20473907 , 153433 },
4037c657876SArnaldo Carvalho de Melo 	{ 20748982 , 153875 },
4047c657876SArnaldo Carvalho de Melo 	{ 21026807 , 154316 },
4057c657876SArnaldo Carvalho de Melo 	{ 21307399 , 154758 },
4067c657876SArnaldo Carvalho de Melo 	{ 21590773 , 155199 },
4077c657876SArnaldo Carvalho de Melo 	{ 21876949 , 155641 },
4087c657876SArnaldo Carvalho de Melo 	{ 22165941 , 156082 },
4097c657876SArnaldo Carvalho de Melo 	{ 22457769 , 156523 },
4107c657876SArnaldo Carvalho de Melo 	{ 22752449 , 156964 },
4117c657876SArnaldo Carvalho de Melo 	{ 23049999 , 157405 },
4127c657876SArnaldo Carvalho de Melo 	{ 23350435 , 157846 },
4137c657876SArnaldo Carvalho de Melo 	{ 23653774 , 158287 },
4147c657876SArnaldo Carvalho de Melo 	{ 23960036 , 158727 },
4157c657876SArnaldo Carvalho de Melo 	{ 24269236 , 159168 },
4167c657876SArnaldo Carvalho de Melo 	{ 24581392 , 159608 },
4177c657876SArnaldo Carvalho de Melo 	{ 24896521 , 160049 },
4187c657876SArnaldo Carvalho de Melo 	{ 25214642 , 160489 },
4197c657876SArnaldo Carvalho de Melo 	{ 25535772 , 160929 },
4207c657876SArnaldo Carvalho de Melo 	{ 25859927 , 161370 },
4217c657876SArnaldo Carvalho de Melo 	{ 26187127 , 161810 },
4227c657876SArnaldo Carvalho de Melo 	{ 26517388 , 162250 },
4237c657876SArnaldo Carvalho de Melo 	{ 26850728 , 162690 },
4247c657876SArnaldo Carvalho de Melo 	{ 27187165 , 163130 },
4257c657876SArnaldo Carvalho de Melo 	{ 27526716 , 163569 },
4267c657876SArnaldo Carvalho de Melo 	{ 27869400 , 164009 },
4277c657876SArnaldo Carvalho de Melo 	{ 28215234 , 164449 },
4287c657876SArnaldo Carvalho de Melo 	{ 28564236 , 164889 },
4297c657876SArnaldo Carvalho de Melo 	{ 28916423 , 165328 },
4307c657876SArnaldo Carvalho de Melo 	{ 29271815 , 165768 },
4317c657876SArnaldo Carvalho de Melo 	{ 29630428 , 166208 },
4327c657876SArnaldo Carvalho de Melo 	{ 29992281 , 166647 },
4337c657876SArnaldo Carvalho de Melo 	{ 30357392 , 167087 },
4347c657876SArnaldo Carvalho de Melo 	{ 30725779 , 167526 },
4357c657876SArnaldo Carvalho de Melo 	{ 31097459 , 167965 },
4367c657876SArnaldo Carvalho de Melo 	{ 31472452 , 168405 },
4377c657876SArnaldo Carvalho de Melo 	{ 31850774 , 168844 },
4387c657876SArnaldo Carvalho de Melo 	{ 32232445 , 169283 },
4397c657876SArnaldo Carvalho de Melo 	{ 32617482 , 169723 },
4407c657876SArnaldo Carvalho de Melo 	{ 33005904 , 170162 },
4417c657876SArnaldo Carvalho de Melo 	{ 33397730 , 170601 },
4427c657876SArnaldo Carvalho de Melo 	{ 33792976 , 171041 },
4437c657876SArnaldo Carvalho de Melo 	{ 34191663 , 171480 },
4447c657876SArnaldo Carvalho de Melo 	{ 34593807 , 171919 },
4457c657876SArnaldo Carvalho de Melo 	{ 34999428 , 172358 },
4467c657876SArnaldo Carvalho de Melo 	{ 35408544 , 172797 },
4477c657876SArnaldo Carvalho de Melo 	{ 35821174 , 173237 },
4487c657876SArnaldo Carvalho de Melo 	{ 36237335 , 173676 },
4497c657876SArnaldo Carvalho de Melo 	{ 36657047 , 174115 },
4507c657876SArnaldo Carvalho de Melo 	{ 37080329 , 174554 },
4517c657876SArnaldo Carvalho de Melo 	{ 37507197 , 174993 },
4527c657876SArnaldo Carvalho de Melo 	{ 37937673 , 175433 },
4537c657876SArnaldo Carvalho de Melo 	{ 38371773 , 175872 },
4547c657876SArnaldo Carvalho de Melo 	{ 38809517 , 176311 },
4557c657876SArnaldo Carvalho de Melo 	{ 39250924 , 176750 },
4567c657876SArnaldo Carvalho de Melo 	{ 39696012 , 177190 },
4577c657876SArnaldo Carvalho de Melo 	{ 40144800 , 177629 },
4587c657876SArnaldo Carvalho de Melo 	{ 40597308 , 178068 },
4597c657876SArnaldo Carvalho de Melo 	{ 41053553 , 178507 },
4607c657876SArnaldo Carvalho de Melo 	{ 41513554 , 178947 },
4617c657876SArnaldo Carvalho de Melo 	{ 41977332 , 179386 },
4627c657876SArnaldo Carvalho de Melo 	{ 42444904 , 179825 },
4637c657876SArnaldo Carvalho de Melo 	{ 42916290 , 180265 },
4647c657876SArnaldo Carvalho de Melo 	{ 43391509 , 180704 },
4657c657876SArnaldo Carvalho de Melo 	{ 43870579 , 181144 },
4667c657876SArnaldo Carvalho de Melo 	{ 44353520 , 181583 },
4677c657876SArnaldo Carvalho de Melo 	{ 44840352 , 182023 },
4687c657876SArnaldo Carvalho de Melo 	{ 45331092 , 182462 },
4697c657876SArnaldo Carvalho de Melo 	{ 45825761 , 182902 },
4707c657876SArnaldo Carvalho de Melo 	{ 46324378 , 183342 },
4717c657876SArnaldo Carvalho de Melo 	{ 46826961 , 183781 },
4727c657876SArnaldo Carvalho de Melo 	{ 47333531 , 184221 },
4737c657876SArnaldo Carvalho de Melo 	{ 47844106 , 184661 },
4747c657876SArnaldo Carvalho de Melo 	{ 48358706 , 185101 },
4757c657876SArnaldo Carvalho de Melo 	{ 48877350 , 185541 },
4767c657876SArnaldo Carvalho de Melo 	{ 49400058 , 185981 },
4777c657876SArnaldo Carvalho de Melo 	{ 49926849 , 186421 },
4787c657876SArnaldo Carvalho de Melo 	{ 50457743 , 186861 },
4797c657876SArnaldo Carvalho de Melo 	{ 50992759 , 187301 },
4807c657876SArnaldo Carvalho de Melo 	{ 51531916 , 187741 },
4817c657876SArnaldo Carvalho de Melo 	{ 52075235 , 188181 },
4827c657876SArnaldo Carvalho de Melo 	{ 52622735 , 188622 },
4837c657876SArnaldo Carvalho de Melo 	{ 53174435 , 189062 },
4847c657876SArnaldo Carvalho de Melo 	{ 53730355 , 189502 },
4857c657876SArnaldo Carvalho de Melo 	{ 54290515 , 189943 },
4867c657876SArnaldo Carvalho de Melo 	{ 54854935 , 190383 },
4877c657876SArnaldo Carvalho de Melo 	{ 55423634 , 190824 },
4887c657876SArnaldo Carvalho de Melo 	{ 55996633 , 191265 },
4897c657876SArnaldo Carvalho de Melo 	{ 56573950 , 191706 },
4907c657876SArnaldo Carvalho de Melo 	{ 57155606 , 192146 },
4917c657876SArnaldo Carvalho de Melo 	{ 57741621 , 192587 },
4927c657876SArnaldo Carvalho de Melo 	{ 58332014 , 193028 },
4937c657876SArnaldo Carvalho de Melo 	{ 58926806 , 193470 },
4947c657876SArnaldo Carvalho de Melo 	{ 59526017 , 193911 },
4957c657876SArnaldo Carvalho de Melo 	{ 60129666 , 194352 },
4967c657876SArnaldo Carvalho de Melo 	{ 60737774 , 194793 },
4977c657876SArnaldo Carvalho de Melo 	{ 61350361 , 195235 },
4987c657876SArnaldo Carvalho de Melo 	{ 61967446 , 195677 },
4997c657876SArnaldo Carvalho de Melo 	{ 62589050 , 196118 },
5007c657876SArnaldo Carvalho de Melo 	{ 63215194 , 196560 },
5017c657876SArnaldo Carvalho de Melo 	{ 63845897 , 197002 },
5027c657876SArnaldo Carvalho de Melo 	{ 64481179 , 197444 },
5037c657876SArnaldo Carvalho de Melo 	{ 65121061 , 197886 },
5047c657876SArnaldo Carvalho de Melo 	{ 65765563 , 198328 },
5057c657876SArnaldo Carvalho de Melo 	{ 66414705 , 198770 },
5067c657876SArnaldo Carvalho de Melo 	{ 67068508 , 199213 },
5077c657876SArnaldo Carvalho de Melo 	{ 67726992 , 199655 },
5087c657876SArnaldo Carvalho de Melo 	{ 68390177 , 200098 },
5097c657876SArnaldo Carvalho de Melo 	{ 69058085 , 200540 },
5107c657876SArnaldo Carvalho de Melo 	{ 69730735 , 200983 },
5117c657876SArnaldo Carvalho de Melo 	{ 70408147 , 201426 },
5127c657876SArnaldo Carvalho de Melo 	{ 71090343 , 201869 },
5137c657876SArnaldo Carvalho de Melo 	{ 71777343 , 202312 },
5147c657876SArnaldo Carvalho de Melo 	{ 72469168 , 202755 },
5157c657876SArnaldo Carvalho de Melo 	{ 73165837 , 203199 },
5167c657876SArnaldo Carvalho de Melo 	{ 73867373 , 203642 },
5177c657876SArnaldo Carvalho de Melo 	{ 74573795 , 204086 },
5187c657876SArnaldo Carvalho de Melo 	{ 75285124 , 204529 },
5197c657876SArnaldo Carvalho de Melo 	{ 76001380 , 204973 },
5207c657876SArnaldo Carvalho de Melo 	{ 76722586 , 205417 },
5217c657876SArnaldo Carvalho de Melo 	{ 77448761 , 205861 },
5227c657876SArnaldo Carvalho de Melo 	{ 78179926 , 206306 },
5237c657876SArnaldo Carvalho de Melo 	{ 78916102 , 206750 },
5247c657876SArnaldo Carvalho de Melo 	{ 79657310 , 207194 },
5257c657876SArnaldo Carvalho de Melo 	{ 80403571 , 207639 },
5267c657876SArnaldo Carvalho de Melo 	{ 81154906 , 208084 },
5277c657876SArnaldo Carvalho de Melo 	{ 81911335 , 208529 },
5287c657876SArnaldo Carvalho de Melo 	{ 82672880 , 208974 },
5297c657876SArnaldo Carvalho de Melo 	{ 83439562 , 209419 },
5307c657876SArnaldo Carvalho de Melo 	{ 84211402 , 209864 },
5317c657876SArnaldo Carvalho de Melo 	{ 84988421 , 210309 },
5327c657876SArnaldo Carvalho de Melo 	{ 85770640 , 210755 },
5337c657876SArnaldo Carvalho de Melo 	{ 86558080 , 211201 },
5347c657876SArnaldo Carvalho de Melo 	{ 87350762 , 211647 },
5357c657876SArnaldo Carvalho de Melo 	{ 88148708 , 212093 },
5367c657876SArnaldo Carvalho de Melo 	{ 88951938 , 212539 },
5377c657876SArnaldo Carvalho de Melo 	{ 89760475 , 212985 },
5387c657876SArnaldo Carvalho de Melo 	{ 90574339 , 213432 },
5397c657876SArnaldo Carvalho de Melo 	{ 91393551 , 213878 },
5407c657876SArnaldo Carvalho de Melo 	{ 92218133 , 214325 },
5417c657876SArnaldo Carvalho de Melo 	{ 93048107 , 214772 },
5427c657876SArnaldo Carvalho de Melo 	{ 93883493 , 215219 },
5437c657876SArnaldo Carvalho de Melo 	{ 94724314 , 215666 },
5447c657876SArnaldo Carvalho de Melo 	{ 95570590 , 216114 },
5457c657876SArnaldo Carvalho de Melo 	{ 96422343 , 216561 },
5467c657876SArnaldo Carvalho de Melo 	{ 97279594 , 217009 },
5477c657876SArnaldo Carvalho de Melo 	{ 98142366 , 217457 },
5487c657876SArnaldo Carvalho de Melo 	{ 99010679 , 217905 },
5497c657876SArnaldo Carvalho de Melo 	{ 99884556 , 218353 },
5507c657876SArnaldo Carvalho de Melo 	{ 100764018 , 218801 },
5517c657876SArnaldo Carvalho de Melo 	{ 101649086 , 219250 },
5527c657876SArnaldo Carvalho de Melo 	{ 102539782 , 219698 },
5537c657876SArnaldo Carvalho de Melo 	{ 103436128 , 220147 },
5547c657876SArnaldo Carvalho de Melo 	{ 104338146 , 220596 },
5557c657876SArnaldo Carvalho de Melo 	{ 105245857 , 221046 },
5567c657876SArnaldo Carvalho de Melo 	{ 106159284 , 221495 },
5577c657876SArnaldo Carvalho de Melo 	{ 107078448 , 221945 },
5587c657876SArnaldo Carvalho de Melo 	{ 108003370 , 222394 },
5597c657876SArnaldo Carvalho de Melo 	{ 108934074 , 222844 },
5607c657876SArnaldo Carvalho de Melo 	{ 109870580 , 223294 },
5617c657876SArnaldo Carvalho de Melo 	{ 110812910 , 223745 },
5627c657876SArnaldo Carvalho de Melo 	{ 111761087 , 224195 },
5637c657876SArnaldo Carvalho de Melo 	{ 112715133 , 224646 },
5647c657876SArnaldo Carvalho de Melo 	{ 113675069 , 225097 },
5657c657876SArnaldo Carvalho de Melo 	{ 114640918 , 225548 },
5667c657876SArnaldo Carvalho de Melo 	{ 115612702 , 225999 },
5677c657876SArnaldo Carvalho de Melo 	{ 116590442 , 226450 },
5687c657876SArnaldo Carvalho de Melo 	{ 117574162 , 226902 },
5697c657876SArnaldo Carvalho de Melo 	{ 118563882 , 227353 },
5707c657876SArnaldo Carvalho de Melo 	{ 119559626 , 227805 },
5717c657876SArnaldo Carvalho de Melo 	{ 120561415 , 228258 },
5727c657876SArnaldo Carvalho de Melo 	{ 121569272 , 228710 },
5737c657876SArnaldo Carvalho de Melo 	{ 122583219 , 229162 },
5747c657876SArnaldo Carvalho de Melo 	{ 123603278 , 229615 },
5757c657876SArnaldo Carvalho de Melo 	{ 124629471 , 230068 },
5767c657876SArnaldo Carvalho de Melo 	{ 125661822 , 230521 },
5777c657876SArnaldo Carvalho de Melo 	{ 126700352 , 230974 },
5787c657876SArnaldo Carvalho de Melo 	{ 127745083 , 231428 },
5797c657876SArnaldo Carvalho de Melo 	{ 128796039 , 231882 },
5807c657876SArnaldo Carvalho de Melo 	{ 129853241 , 232336 },
5817c657876SArnaldo Carvalho de Melo 	{ 130916713 , 232790 },
5827c657876SArnaldo Carvalho de Melo 	{ 131986475 , 233244 },
5837c657876SArnaldo Carvalho de Melo 	{ 133062553 , 233699 },
5847c657876SArnaldo Carvalho de Melo 	{ 134144966 , 234153 },
5857c657876SArnaldo Carvalho de Melo 	{ 135233739 , 234608 },
5867c657876SArnaldo Carvalho de Melo 	{ 136328894 , 235064 },
5877c657876SArnaldo Carvalho de Melo 	{ 137430453 , 235519 },
5887c657876SArnaldo Carvalho de Melo 	{ 138538440 , 235975 },
5897c657876SArnaldo Carvalho de Melo 	{ 139652876 , 236430 },
5907c657876SArnaldo Carvalho de Melo 	{ 140773786 , 236886 },
5917c657876SArnaldo Carvalho de Melo 	{ 141901190 , 237343 },
5927c657876SArnaldo Carvalho de Melo 	{ 143035113 , 237799 },
5937c657876SArnaldo Carvalho de Melo 	{ 144175576 , 238256 },
5947c657876SArnaldo Carvalho de Melo 	{ 145322604 , 238713 },
5957c657876SArnaldo Carvalho de Melo 	{ 146476218 , 239170 },
5967c657876SArnaldo Carvalho de Melo 	{ 147636442 , 239627 },
5977c657876SArnaldo Carvalho de Melo 	{ 148803298 , 240085 },
5987c657876SArnaldo Carvalho de Melo 	{ 149976809 , 240542 },
5997c657876SArnaldo Carvalho de Melo 	{ 151156999 , 241000 },
6007c657876SArnaldo Carvalho de Melo 	{ 152343890 , 241459 },
6017c657876SArnaldo Carvalho de Melo 	{ 153537506 , 241917 },
6027c657876SArnaldo Carvalho de Melo 	{ 154737869 , 242376 },
6037c657876SArnaldo Carvalho de Melo 	{ 155945002 , 242835 },
6047c657876SArnaldo Carvalho de Melo 	{ 157158929 , 243294 },
6057c657876SArnaldo Carvalho de Melo 	{ 158379673 , 243753 },
6067c657876SArnaldo Carvalho de Melo 	{ 159607257 , 244213 },
6077c657876SArnaldo Carvalho de Melo 	{ 160841704 , 244673 },
6087c657876SArnaldo Carvalho de Melo 	{ 162083037 , 245133 },
6097c657876SArnaldo Carvalho de Melo 	{ 163331279 , 245593 },
6107c657876SArnaldo Carvalho de Melo 	{ 164586455 , 246054 },
6117c657876SArnaldo Carvalho de Melo 	{ 165848586 , 246514 },
6127c657876SArnaldo Carvalho de Melo 	{ 167117696 , 246975 },
6137c657876SArnaldo Carvalho de Melo 	{ 168393810 , 247437 },
6147c657876SArnaldo Carvalho de Melo 	{ 169676949 , 247898 },
6157c657876SArnaldo Carvalho de Melo 	{ 170967138 , 248360 },
6167c657876SArnaldo Carvalho de Melo 	{ 172264399 , 248822 },
6177c657876SArnaldo Carvalho de Melo 	{ 173568757 , 249284 },
6187c657876SArnaldo Carvalho de Melo 	{ 174880235 , 249747 },
6197c657876SArnaldo Carvalho de Melo 	{ 176198856 , 250209 },
6207c657876SArnaldo Carvalho de Melo 	{ 177524643 , 250672 },
6217c657876SArnaldo Carvalho de Melo 	{ 178857621 , 251136 },
6227c657876SArnaldo Carvalho de Melo 	{ 180197813 , 251599 },
6237c657876SArnaldo Carvalho de Melo 	{ 181545242 , 252063 },
6247c657876SArnaldo Carvalho de Melo 	{ 182899933 , 252527 },
6257c657876SArnaldo Carvalho de Melo 	{ 184261908 , 252991 },
6267c657876SArnaldo Carvalho de Melo 	{ 185631191 , 253456 },
6277c657876SArnaldo Carvalho de Melo 	{ 187007807 , 253920 },
6287c657876SArnaldo Carvalho de Melo 	{ 188391778 , 254385 },
6297c657876SArnaldo Carvalho de Melo 	{ 189783129 , 254851 },
6307c657876SArnaldo Carvalho de Melo 	{ 191181884 , 255316 },
6317c657876SArnaldo Carvalho de Melo 	{ 192588065 , 255782 },
6327c657876SArnaldo Carvalho de Melo 	{ 194001698 , 256248 },
6337c657876SArnaldo Carvalho de Melo 	{ 195422805 , 256714 },
6347c657876SArnaldo Carvalho de Melo 	{ 196851411 , 257181 },
6357c657876SArnaldo Carvalho de Melo 	{ 198287540 , 257648 },
6367c657876SArnaldo Carvalho de Melo 	{ 199731215 , 258115 },
6377c657876SArnaldo Carvalho de Melo 	{ 201182461 , 258582 },
6387c657876SArnaldo Carvalho de Melo 	{ 202641302 , 259050 },
6397c657876SArnaldo Carvalho de Melo 	{ 204107760 , 259518 },
6407c657876SArnaldo Carvalho de Melo 	{ 205581862 , 259986 },
6417c657876SArnaldo Carvalho de Melo 	{ 207063630 , 260454 },
6427c657876SArnaldo Carvalho de Melo 	{ 208553088 , 260923 },
6437c657876SArnaldo Carvalho de Melo 	{ 210050262 , 261392 },
6447c657876SArnaldo Carvalho de Melo 	{ 211555174 , 261861 },
6457c657876SArnaldo Carvalho de Melo 	{ 213067849 , 262331 },
6467c657876SArnaldo Carvalho de Melo 	{ 214588312 , 262800 },
6477c657876SArnaldo Carvalho de Melo 	{ 216116586 , 263270 },
6487c657876SArnaldo Carvalho de Melo 	{ 217652696 , 263741 },
6497c657876SArnaldo Carvalho de Melo 	{ 219196666 , 264211 },
6507c657876SArnaldo Carvalho de Melo 	{ 220748520 , 264682 },
6517c657876SArnaldo Carvalho de Melo 	{ 222308282 , 265153 },
6527c657876SArnaldo Carvalho de Melo 	{ 223875978 , 265625 },
6537c657876SArnaldo Carvalho de Melo 	{ 225451630 , 266097 },
6547c657876SArnaldo Carvalho de Melo 	{ 227035265 , 266569 },
6557c657876SArnaldo Carvalho de Melo 	{ 228626905 , 267041 },
6567c657876SArnaldo Carvalho de Melo 	{ 230226576 , 267514 },
6577c657876SArnaldo Carvalho de Melo 	{ 231834302 , 267986 },
6587c657876SArnaldo Carvalho de Melo 	{ 233450107 , 268460 },
6597c657876SArnaldo Carvalho de Melo 	{ 235074016 , 268933 },
6607c657876SArnaldo Carvalho de Melo 	{ 236706054 , 269407 },
6617c657876SArnaldo Carvalho de Melo 	{ 238346244 , 269881 },
6627c657876SArnaldo Carvalho de Melo 	{ 239994613 , 270355 },
6637c657876SArnaldo Carvalho de Melo 	{ 241651183 , 270830 },
6647c657876SArnaldo Carvalho de Melo 	{ 243315981 , 271305 }
6657c657876SArnaldo Carvalho de Melo };
6667c657876SArnaldo Carvalho de Melo 
6677c657876SArnaldo Carvalho de Melo /* Calculate the send rate as per section 3.1 of RFC3448
6687c657876SArnaldo Carvalho de Melo 
6697c657876SArnaldo Carvalho de Melo Returns send rate in bytes per second
6707c657876SArnaldo Carvalho de Melo 
6717c657876SArnaldo Carvalho de Melo Integer maths and lookups are used as not allowed floating point in kernel
6727c657876SArnaldo Carvalho de Melo 
6737c657876SArnaldo Carvalho de Melo The function for Xcalc as per section 3.1 of RFC3448 is:
6747c657876SArnaldo Carvalho de Melo 
6757c657876SArnaldo Carvalho de Melo X =                            s
6767c657876SArnaldo Carvalho de Melo      -------------------------------------------------------------
6777c657876SArnaldo Carvalho de Melo      R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2)))
6787c657876SArnaldo Carvalho de Melo 
6797c657876SArnaldo Carvalho de Melo where
6807c657876SArnaldo Carvalho de Melo X is the trasmit rate in bytes/second
6817c657876SArnaldo Carvalho de Melo s is the packet size in bytes
6827c657876SArnaldo Carvalho de Melo R is the round trip time in seconds
6837c657876SArnaldo Carvalho de Melo p is the loss event rate, between 0 and 1.0, of the number of loss events
6847c657876SArnaldo Carvalho de Melo   as a fraction of the number of packets transmitted
6857c657876SArnaldo Carvalho de Melo t_RTO is the TCP retransmission timeout value in seconds
6867c657876SArnaldo Carvalho de Melo b is the number of packets acknowledged by a single TCP acknowledgement
6877c657876SArnaldo Carvalho de Melo 
6887c657876SArnaldo Carvalho de Melo we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
6897c657876SArnaldo Carvalho de Melo 
6907c657876SArnaldo Carvalho de Melo X =                            s
6917c657876SArnaldo Carvalho de Melo      -----------------------------------------------------------------------
6927c657876SArnaldo Carvalho de Melo      R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
6937c657876SArnaldo Carvalho de Melo 
6947c657876SArnaldo Carvalho de Melo 
6957c657876SArnaldo Carvalho de Melo which we can break down into:
6967c657876SArnaldo Carvalho de Melo 
6977c657876SArnaldo Carvalho de Melo X =     s
6987c657876SArnaldo Carvalho de Melo      --------
6997c657876SArnaldo Carvalho de Melo      R * f(p)
7007c657876SArnaldo Carvalho de Melo 
7017c657876SArnaldo Carvalho de Melo where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
7027c657876SArnaldo Carvalho de Melo 
7037c657876SArnaldo Carvalho de Melo Function parameters:
7047c657876SArnaldo Carvalho de Melo s - bytes
7057c657876SArnaldo Carvalho de Melo R - RTT in usecs
7067c657876SArnaldo Carvalho de Melo p - loss rate (decimal fraction multiplied by 1,000,000)
7077c657876SArnaldo Carvalho de Melo 
7087c657876SArnaldo Carvalho de Melo Returns Xcalc in bytes per second
7097c657876SArnaldo Carvalho de Melo 
7107c657876SArnaldo Carvalho de Melo DON'T alter this code unless you run test cases against it as the code
7117c657876SArnaldo Carvalho de Melo has been manipulated to stop underflow/overlow.
7127c657876SArnaldo Carvalho de Melo 
7137c657876SArnaldo Carvalho de Melo */
7147c657876SArnaldo Carvalho de Melo static u32 ccid3_calc_x(u16 s, u32 R, u32 p)
7157c657876SArnaldo Carvalho de Melo {
7167c657876SArnaldo Carvalho de Melo 	int index;
7177c657876SArnaldo Carvalho de Melo 	u32 f;
7187c657876SArnaldo Carvalho de Melo 	u64 tmp1, tmp2;
7197c657876SArnaldo Carvalho de Melo 
7207c657876SArnaldo Carvalho de Melo 	if (p < CALCX_SPLIT)
7217c657876SArnaldo Carvalho de Melo 		index = (p / (CALCX_SPLIT / CALCX_ARRSIZE)) - 1;
7227c657876SArnaldo Carvalho de Melo 	else
7237c657876SArnaldo Carvalho de Melo 		index = (p / (1000000 / CALCX_ARRSIZE)) - 1;
7247c657876SArnaldo Carvalho de Melo 
7257c657876SArnaldo Carvalho de Melo 	if (index < 0)
7267c657876SArnaldo Carvalho de Melo 		/* p should be 0 unless there is a bug in my code */
7277c657876SArnaldo Carvalho de Melo 		index = 0;
7287c657876SArnaldo Carvalho de Melo 
7297c657876SArnaldo Carvalho de Melo 	if (R == 0)
7307c657876SArnaldo Carvalho de Melo 		R = 1; /* RTT can't be zero or else divide by zero */
7317c657876SArnaldo Carvalho de Melo 
7327c657876SArnaldo Carvalho de Melo 	BUG_ON(index >= CALCX_ARRSIZE);
7337c657876SArnaldo Carvalho de Melo 
7347c657876SArnaldo Carvalho de Melo 	if (p >= CALCX_SPLIT)
7357c657876SArnaldo Carvalho de Melo 		f = calcx_lookup[index][0];
7367c657876SArnaldo Carvalho de Melo 	else
7377c657876SArnaldo Carvalho de Melo 		f = calcx_lookup[index][1];
7387c657876SArnaldo Carvalho de Melo 
7397c657876SArnaldo Carvalho de Melo 	tmp1 = ((u64)s * 100000000);
7407c657876SArnaldo Carvalho de Melo 	tmp2 = ((u64)R * (u64)f);
7417c657876SArnaldo Carvalho de Melo 	do_div(tmp2,10000);
7427c657876SArnaldo Carvalho de Melo 	do_div(tmp1,tmp2);
7437c657876SArnaldo Carvalho de Melo 	/* don't alter above math unless you test due to overflow on 32 bit */
7447c657876SArnaldo Carvalho de Melo 
7457c657876SArnaldo Carvalho de Melo 	return (u32)tmp1;
7467c657876SArnaldo Carvalho de Melo }
7477c657876SArnaldo Carvalho de Melo 
7487c657876SArnaldo Carvalho de Melo /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
7497c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
7507c657876SArnaldo Carvalho de Melo {
7517c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK)
7527c657876SArnaldo Carvalho de Melo 		return;
7537c657876SArnaldo Carvalho de Melo 	/* if no feedback spec says t_ipi is 1 second (set elsewhere and then
7547c657876SArnaldo Carvalho de Melo 	 * doubles after every no feedback timer (separate function) */
7557c657876SArnaldo Carvalho de Melo 
7567c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x < 10) {
7577c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("ccid3_calc_new_t_ipi - ccid3hctx_x < 10\n");
7587c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 10;
7597c657876SArnaldo Carvalho de Melo 	}
7607c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_t_ipi = (hctx->ccid3hctx_s * 100000)
7617c657876SArnaldo Carvalho de Melo 		/ (hctx->ccid3hctx_x / 10);
7627c657876SArnaldo Carvalho de Melo 	/* reason for above maths with 10 in there is to avoid 32 bit
7637c657876SArnaldo Carvalho de Melo 	 * overflow for jumbo packets */
7647c657876SArnaldo Carvalho de Melo 
7657c657876SArnaldo Carvalho de Melo }
7667c657876SArnaldo Carvalho de Melo 
7677c657876SArnaldo Carvalho de Melo /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
7687c657876SArnaldo Carvalho de Melo static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
7697c657876SArnaldo Carvalho de Melo {
7701f2333aeSArnaldo Carvalho de Melo 	hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
7711f2333aeSArnaldo Carvalho de Melo 					   TFRC_OPSYS_HALF_TIME_GRAN);
7727c657876SArnaldo Carvalho de Melo 
7737c657876SArnaldo Carvalho de Melo }
7747c657876SArnaldo Carvalho de Melo 
7757c657876SArnaldo Carvalho de Melo /*
7767c657876SArnaldo Carvalho de Melo  * Update X by
7777c657876SArnaldo Carvalho de Melo  *    If (p > 0)
7787c657876SArnaldo Carvalho de Melo  *       x_calc = calcX(s, R, p);
7797c657876SArnaldo Carvalho de Melo  *       X = max(min(X_calc, 2 * X_recv), s / t_mbi);
7807c657876SArnaldo Carvalho de Melo  *    Else
7817c657876SArnaldo Carvalho de Melo  *       If (now - tld >= R)
7827c657876SArnaldo Carvalho de Melo  *          X = max(min(2 * X, 2 * X_recv), s / R);
7837c657876SArnaldo Carvalho de Melo  *          tld = now;
7847c657876SArnaldo Carvalho de Melo  */
7857c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_update_x(struct sock *sk)
7867c657876SArnaldo Carvalho de Melo {
7877c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
7887c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
7897c657876SArnaldo Carvalho de Melo 
7901f2333aeSArnaldo Carvalho de Melo 	/* To avoid large error in calcX */
7911f2333aeSArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
7927c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x_calc = ccid3_calc_x(hctx->ccid3hctx_s,
7937c657876SArnaldo Carvalho de Melo 						      hctx->ccid3hctx_rtt,
7947c657876SArnaldo Carvalho de Melo 						      hctx->ccid3hctx_p);
7951f2333aeSArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc,
7961f2333aeSArnaldo Carvalho de Melo 							  2 * hctx->ccid3hctx_x_recv),
7971f2333aeSArnaldo Carvalho de Melo 					       (hctx->ccid3hctx_s /
7981f2333aeSArnaldo Carvalho de Melo 					        TFRC_MAX_BACK_OFF_TIME));
799b6ee3d4aSArnaldo Carvalho de Melo 	} else {
800b6ee3d4aSArnaldo Carvalho de Melo 		struct timeval now;
801b6ee3d4aSArnaldo Carvalho de Melo 
802b6ee3d4aSArnaldo Carvalho de Melo 		do_gettimeofday(&now);
803b6ee3d4aSArnaldo Carvalho de Melo 	       	if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >=
804b6ee3d4aSArnaldo Carvalho de Melo 		    hctx->ccid3hctx_rtt) {
805b6ee3d4aSArnaldo Carvalho de Melo 			/* Avoid divide by zero below */
806b6ee3d4aSArnaldo Carvalho de Melo 			const u32 rtt = max_t(u32, hctx->ccid3hctx_rtt, 10);
8077c657876SArnaldo Carvalho de Melo 
8081f2333aeSArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = max_t(u32, min_t(u32, 2 * hctx->ccid3hctx_x_recv,
8091f2333aeSArnaldo Carvalho de Melo 								  2 * hctx->ccid3hctx_x),
8101f2333aeSArnaldo Carvalho de Melo 						       ((hctx->ccid3hctx_s * 100000) /
8111f2333aeSArnaldo Carvalho de Melo 							(rtt / 10)));
8127c657876SArnaldo Carvalho de Melo 			/* Using 100000 and 10 to avoid 32 bit overflow for jumbo frames */
813b6ee3d4aSArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_ld = now;
814b6ee3d4aSArnaldo Carvalho de Melo 		}
8157c657876SArnaldo Carvalho de Melo 	}
8167c657876SArnaldo Carvalho de Melo 
8177c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x == 0) {
8187c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("ccid3hctx_x = 0!\n");
8197c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 1;
8207c657876SArnaldo Carvalho de Melo 	}
8217c657876SArnaldo Carvalho de Melo }
8227c657876SArnaldo Carvalho de Melo 
8237c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
8247c657876SArnaldo Carvalho de Melo {
8257c657876SArnaldo Carvalho de Melo 	struct sock *sk = (struct sock *)data;
8267c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
8277c657876SArnaldo Carvalho de Melo 	unsigned long next_tmout = 0;
8287c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
8297c657876SArnaldo Carvalho de Melo 	u32 rtt;
8307c657876SArnaldo Carvalho de Melo 
8317c657876SArnaldo Carvalho de Melo 	bh_lock_sock(sk);
8327c657876SArnaldo Carvalho de Melo 	if (sock_owned_by_user(sk)) {
8337c657876SArnaldo Carvalho de Melo 		/* Try again later. */
8347c657876SArnaldo Carvalho de Melo 		/* XXX: set some sensible MIB */
8351f2333aeSArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
8361f2333aeSArnaldo Carvalho de Melo 			       jiffies + HZ / 5);
8377c657876SArnaldo Carvalho de Melo 		goto out;
8387c657876SArnaldo Carvalho de Melo 	}
8397c657876SArnaldo Carvalho de Melo 
8407c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
8417c657876SArnaldo Carvalho de Melo 		       ccid3_tx_state_name(hctx->ccid3hctx_state));
8427c657876SArnaldo Carvalho de Melo 
8437c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_x < 10) {
8447c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("TFRC_SSTATE_NO_FBACK ccid3hctx_x < 10\n");
8457c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x = 10;
8467c657876SArnaldo Carvalho de Melo 	}
8477c657876SArnaldo Carvalho de Melo 
8487c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
8497c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_TERM:
8507c657876SArnaldo Carvalho de Melo 		goto out;
8517c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
8527c657876SArnaldo Carvalho de Melo 		/* Halve send rate */
8537c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_x /= 2;
8541f2333aeSArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x <
8551f2333aeSArnaldo Carvalho de Melo 		    (hctx->ccid3hctx_s / TFRC_MAX_BACK_OFF_TIME))
8561f2333aeSArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = (hctx->ccid3hctx_s /
8571f2333aeSArnaldo Carvalho de Melo 					     TFRC_MAX_BACK_OFF_TIME);
8587c657876SArnaldo Carvalho de Melo 
8591f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d "
8601f2333aeSArnaldo Carvalho de Melo 			       "bytes/s\n",
8611f2333aeSArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
8621f2333aeSArnaldo Carvalho de Melo 			       ccid3_tx_state_name(hctx->ccid3hctx_state),
8637c657876SArnaldo Carvalho de Melo 			       hctx->ccid3hctx_x);
8641f2333aeSArnaldo Carvalho de Melo 		next_tmout = max_t(u32, 2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10),
8651f2333aeSArnaldo Carvalho de Melo 					TFRC_INITIAL_TIMEOUT);
8667c657876SArnaldo Carvalho de Melo 		/* do above maths with 100000 and 10 to prevent overflow on 32 bit */
8671f2333aeSArnaldo Carvalho de Melo 		/*
8681f2333aeSArnaldo Carvalho de Melo 		 * FIXME - not sure above calculation is correct. See section
8691f2333aeSArnaldo Carvalho de Melo 		 * 5 of CCID3 11 should adjust tx_t_ipi and double that to
8701f2333aeSArnaldo Carvalho de Melo 		 * achieve it really
8711f2333aeSArnaldo Carvalho de Melo 		 */
8727c657876SArnaldo Carvalho de Melo 		break;
8737c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
8741f2333aeSArnaldo Carvalho de Melo 		/*
8751f2333aeSArnaldo Carvalho de Melo 		 * Check if IDLE since last timeout and recv rate is less than
8761f2333aeSArnaldo Carvalho de Melo 		 * 4 packets per RTT
8771f2333aeSArnaldo Carvalho de Melo 		 */
8787c657876SArnaldo Carvalho de Melo 		rtt = hctx->ccid3hctx_rtt;
8797c657876SArnaldo Carvalho de Melo 		if (rtt < 10)
8807c657876SArnaldo Carvalho de Melo 			rtt = 10;
8817c657876SArnaldo Carvalho de Melo 		/* stop divide by zero below */
8821f2333aeSArnaldo Carvalho de Melo 		if (!hctx->ccid3hctx_idle ||
8831f2333aeSArnaldo Carvalho de Melo 		    (hctx->ccid3hctx_x_recv >= 4 * (hctx->ccid3hctx_s * 100000) / (rtt / 10))) {
8841f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n",
8851f2333aeSArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
8867c657876SArnaldo Carvalho de Melo 				       ccid3_tx_state_name(hctx->ccid3hctx_state));
8877c657876SArnaldo Carvalho de Melo 			/* Halve sending rate */
8887c657876SArnaldo Carvalho de Melo 
8897c657876SArnaldo Carvalho de Melo 			/*  If (X_calc > 2 * X_recv)
8907c657876SArnaldo Carvalho de Melo 			 *    X_recv = max(X_recv / 2, s / (2 * t_mbi));
8917c657876SArnaldo Carvalho de Melo 			 *  Else
8927c657876SArnaldo Carvalho de Melo 			 *    X_recv = X_calc / 4;
8937c657876SArnaldo Carvalho de Melo 			 */
8941f2333aeSArnaldo Carvalho de Melo 			BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P &&
8951f2333aeSArnaldo Carvalho de Melo 			       hctx->ccid3hctx_x_calc == 0);
8967c657876SArnaldo Carvalho de Melo 
8977c657876SArnaldo Carvalho de Melo 			/* check also if p is zero -> x_calc is infinity? */
8987c657876SArnaldo Carvalho de Melo 			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
8997c657876SArnaldo Carvalho de Melo 			    hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
9007c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
9017c657876SArnaldo Carvalho de Melo 								    hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME));
9027c657876SArnaldo Carvalho de Melo 			else
9037c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4;
9047c657876SArnaldo Carvalho de Melo 
9057c657876SArnaldo Carvalho de Melo 			/* Update sending rate */
9067c657876SArnaldo Carvalho de Melo 			ccid3_hc_tx_update_x(sk);
9077c657876SArnaldo Carvalho de Melo 		}
9087c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x == 0) {
9097c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("TFRC_SSTATE_FBACK ccid3hctx_x = 0!\n");
9107c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = 10;
9117c657876SArnaldo Carvalho de Melo 		}
9127c657876SArnaldo Carvalho de Melo 		/* Schedule no feedback timer to expire in max(4 * R, 2 * s / X) */
913c68e64cfSArnaldo Carvalho de Melo 		next_tmout = max_t(u32, hctx->ccid3hctx_t_rto,
9147c657876SArnaldo Carvalho de Melo 				   2 * (hctx->ccid3hctx_s * 100000) / (hctx->ccid3hctx_x / 10));
9157c657876SArnaldo Carvalho de Melo 		break;
9167c657876SArnaldo Carvalho de Melo 	default:
9177c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
9187c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
9197c657876SArnaldo Carvalho de Melo 		dump_stack();
9207c657876SArnaldo Carvalho de Melo 		goto out;
9217c657876SArnaldo Carvalho de Melo 	}
9227c657876SArnaldo Carvalho de Melo 
9237c657876SArnaldo Carvalho de Melo 	sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
9247c657876SArnaldo Carvalho de Melo 		      jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
9257c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_idle = 1;
9267c657876SArnaldo Carvalho de Melo out:
9277c657876SArnaldo Carvalho de Melo 	bh_unlock_sock(sk);
9287c657876SArnaldo Carvalho de Melo 	sock_put(sk);
9297c657876SArnaldo Carvalho de Melo }
9307c657876SArnaldo Carvalho de Melo 
93127258ee5SArnaldo Carvalho de Melo static int ccid3_hc_tx_send_packet(struct sock *sk,
93227258ee5SArnaldo Carvalho de Melo 				   struct sk_buff *skb, int len)
9337c657876SArnaldo Carvalho de Melo {
9347c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
9357c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
9368c60f3faSArnaldo Carvalho de Melo 	struct dccp_tx_hist_entry *new_packet;
9377c657876SArnaldo Carvalho de Melo 	struct timeval now;
93827258ee5SArnaldo Carvalho de Melo 	long delay;
9397c657876SArnaldo Carvalho de Melo 	int rc = -ENOTCONN;
9407c657876SArnaldo Carvalho de Melo 
9411f2333aeSArnaldo Carvalho de Melo 	/* Check if pure ACK or Terminating*/
9421f2333aeSArnaldo Carvalho de Melo 
9437c657876SArnaldo Carvalho de Melo 	/*
9441f2333aeSArnaldo Carvalho de Melo 	 * XXX: We only call this function for DATA and DATAACK, on, these
9451f2333aeSArnaldo Carvalho de Melo 	 * packets can have zero length, but why the comment about "pure ACK"?
9467c657876SArnaldo Carvalho de Melo 	 */
9471f2333aeSArnaldo Carvalho de Melo 	if (hctx == NULL || len == 0 ||
9481f2333aeSArnaldo Carvalho de Melo 	    hctx->ccid3hctx_state == TFRC_SSTATE_TERM)
9497c657876SArnaldo Carvalho de Melo 		goto out;
9507c657876SArnaldo Carvalho de Melo 
9517c657876SArnaldo Carvalho de Melo 	/* See if last packet allocated was not sent */
9528c60f3faSArnaldo Carvalho de Melo 	new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
9538c60f3faSArnaldo Carvalho de Melo 	if (new_packet == NULL || new_packet->dccphtx_sent) {
9541f2333aeSArnaldo Carvalho de Melo 		new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
9551f2333aeSArnaldo Carvalho de Melo 						    SLAB_ATOMIC);
9567c657876SArnaldo Carvalho de Melo 
9577c657876SArnaldo Carvalho de Melo 		rc = -ENOBUFS;
9587c657876SArnaldo Carvalho de Melo 		if (new_packet == NULL) {
9597c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, not enough mem to add "
9601f2333aeSArnaldo Carvalho de Melo 				       "to history, send refused\n",
9611f2333aeSArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
9627c657876SArnaldo Carvalho de Melo 			goto out;
9637c657876SArnaldo Carvalho de Melo 		}
9647c657876SArnaldo Carvalho de Melo 
9658c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
9667c657876SArnaldo Carvalho de Melo 	}
9677c657876SArnaldo Carvalho de Melo 
9687c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
9697c657876SArnaldo Carvalho de Melo 
9707c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
9717c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
9721f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, first packet(%llu)\n",
9731f2333aeSArnaldo Carvalho de Melo 			       dccp_role(sk), sk, dp->dccps_gss);
9747c657876SArnaldo Carvalho de Melo 
9757c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer;
9767c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_no_feedback_timer.data     = (unsigned long)sk;
9771f2333aeSArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
9781f2333aeSArnaldo Carvalho de Melo 			       jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT));
9797c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_last_win_count	 = 0;
9807c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_last_win_count = now;
9817c657876SArnaldo Carvalho de Melo 		ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
9827c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_ipi = TFRC_INITIAL_TIMEOUT;
9837c657876SArnaldo Carvalho de Melo 
9847c657876SArnaldo Carvalho de Melo 		/* Set nominal send time for initial packet */
9857c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_nom = now;
986b6ee3d4aSArnaldo Carvalho de Melo 		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
987b6ee3d4aSArnaldo Carvalho de Melo 				  hctx->ccid3hctx_t_ipi);
9887c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_delta(hctx);
9897c657876SArnaldo Carvalho de Melo 		rc = 0;
9907c657876SArnaldo Carvalho de Melo 		break;
9917c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
9927c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
993b6ee3d4aSArnaldo Carvalho de Melo 		delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
994b6ee3d4aSArnaldo Carvalho de Melo 		         hctx->ccid3hctx_delta);
99527258ee5SArnaldo Carvalho de Melo 		ccid3_pr_debug("send_packet delay=%ld\n", delay);
99627258ee5SArnaldo Carvalho de Melo 		delay /= -1000;
9977c657876SArnaldo Carvalho de Melo 		/* divide by -1000 is to convert to ms and get sign right */
998d6809c12SArnaldo Carvalho de Melo 		rc = delay > 0 ? delay : 0;
9997c657876SArnaldo Carvalho de Melo 		break;
10007c657876SArnaldo Carvalho de Melo 	default:
10017c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
10027c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
10037c657876SArnaldo Carvalho de Melo 		dump_stack();
10047c657876SArnaldo Carvalho de Melo 		rc = -EINVAL;
10057c657876SArnaldo Carvalho de Melo 		break;
10067c657876SArnaldo Carvalho de Melo 	}
10077c657876SArnaldo Carvalho de Melo 
10087c657876SArnaldo Carvalho de Melo 	/* Can we send? if so add options and add to packet history */
10097c657876SArnaldo Carvalho de Melo 	if (rc == 0)
1010c1734376SArnaldo Carvalho de Melo 		new_packet->dccphtx_ccval =
10118c60f3faSArnaldo Carvalho de Melo 			DCCP_SKB_CB(skb)->dccpd_ccval =
10128c60f3faSArnaldo Carvalho de Melo 				hctx->ccid3hctx_last_win_count;
10137c657876SArnaldo Carvalho de Melo out:
10147c657876SArnaldo Carvalho de Melo 	return rc;
10157c657876SArnaldo Carvalho de Melo }
10167c657876SArnaldo Carvalho de Melo 
10177c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
10187c657876SArnaldo Carvalho de Melo {
10197c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
10207c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
10217c657876SArnaldo Carvalho de Melo 	struct timeval now;
10227c657876SArnaldo Carvalho de Melo 
10237c657876SArnaldo Carvalho de Melo 	BUG_ON(hctx == NULL);
10247c657876SArnaldo Carvalho de Melo 
10257c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
10267c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, while state is TFRC_SSTATE_TERM!\n",
10277c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
10287c657876SArnaldo Carvalho de Melo 		return;
10297c657876SArnaldo Carvalho de Melo 	}
10307c657876SArnaldo Carvalho de Melo 
10317c657876SArnaldo Carvalho de Melo 	do_gettimeofday(&now);
10327c657876SArnaldo Carvalho de Melo 
10337c657876SArnaldo Carvalho de Melo 	/* check if we have sent a data packet */
10347c657876SArnaldo Carvalho de Melo 	if (len > 0) {
10357c657876SArnaldo Carvalho de Melo 		unsigned long quarter_rtt;
10368c60f3faSArnaldo Carvalho de Melo 		struct dccp_tx_hist_entry *packet;
10377c657876SArnaldo Carvalho de Melo 
10388c60f3faSArnaldo Carvalho de Melo 		packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
10398c60f3faSArnaldo Carvalho de Melo 		if (packet == NULL) {
10401f2333aeSArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: packet doesn't exists in "
10411f2333aeSArnaldo Carvalho de Melo 					 "history!\n", __FUNCTION__);
10427c657876SArnaldo Carvalho de Melo 			return;
10437c657876SArnaldo Carvalho de Melo 		}
10448c60f3faSArnaldo Carvalho de Melo 		if (packet->dccphtx_sent) {
10451f2333aeSArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: no unsent packet in history!\n",
10461f2333aeSArnaldo Carvalho de Melo 			       __FUNCTION__);
10477c657876SArnaldo Carvalho de Melo 			return;
10487c657876SArnaldo Carvalho de Melo 		}
10498c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_tstamp = now;
10508c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_seqno  = dp->dccps_gss;
10517c657876SArnaldo Carvalho de Melo 		/*
10521f2333aeSArnaldo Carvalho de Melo 		 * Check if win_count have changed
10531f2333aeSArnaldo Carvalho de Melo 		 * Algorithm in "8.1. Window Counter Valuer" in
10541f2333aeSArnaldo Carvalho de Melo 		 * draft-ietf-dccp-ccid3-11.txt
10557c657876SArnaldo Carvalho de Melo 		 */
1056b6ee3d4aSArnaldo Carvalho de Melo 		quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count) /
10571f2333aeSArnaldo Carvalho de Melo 			      (hctx->ccid3hctx_rtt / 4);
10587c657876SArnaldo Carvalho de Melo 		if (quarter_rtt > 0) {
10597c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_last_win_count = now;
10607c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_last_win_count	 = (hctx->ccid3hctx_last_win_count +
10617c657876SArnaldo Carvalho de Melo 							    min_t(unsigned long, quarter_rtt, 5)) % 16;
10621f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, window changed from "
10631f2333aeSArnaldo Carvalho de Melo 				       "%u to %u!\n",
10647c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
1065c1734376SArnaldo Carvalho de Melo 				       packet->dccphtx_ccval,
10667c657876SArnaldo Carvalho de Melo 				       hctx->ccid3hctx_last_win_count);
10677c657876SArnaldo Carvalho de Melo 		}
10681f2333aeSArnaldo Carvalho de Melo 
10697c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_idle = 0;
1070c1734376SArnaldo Carvalho de Melo 		packet->dccphtx_rtt  = hctx->ccid3hctx_rtt;
10718c60f3faSArnaldo Carvalho de Melo 		packet->dccphtx_sent = 1;
10727c657876SArnaldo Carvalho de Melo 	} else
10737c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
10747c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, dp->dccps_gss);
10757c657876SArnaldo Carvalho de Melo 
10767c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
10777c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
10787c657876SArnaldo Carvalho de Melo 		/* if first wasn't pure ack */
10797c657876SArnaldo Carvalho de Melo 		if (len != 0)
10801f2333aeSArnaldo Carvalho de Melo 			printk(KERN_CRIT "%s: %s, First packet sent is noted "
10811f2333aeSArnaldo Carvalho de Melo 					 "as a data packet\n",
10827c657876SArnaldo Carvalho de Melo 			       __FUNCTION__, dccp_role(sk));
10837c657876SArnaldo Carvalho de Melo 		return;
10847c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
10857c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
10867c657876SArnaldo Carvalho de Melo 		if (len > 0) {
10877c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_t_nom = now;
10887c657876SArnaldo Carvalho de Melo 			ccid3_calc_new_t_ipi(hctx);
10897c657876SArnaldo Carvalho de Melo 			ccid3_calc_new_delta(hctx);
1090b6ee3d4aSArnaldo Carvalho de Melo 			timeval_add_usecs(&hctx->ccid3hctx_t_nom,
1091b6ee3d4aSArnaldo Carvalho de Melo 					  hctx->ccid3hctx_t_ipi);
10927c657876SArnaldo Carvalho de Melo 		}
10937c657876SArnaldo Carvalho de Melo 		break;
10947c657876SArnaldo Carvalho de Melo 	default:
10957c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
10967c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
10977c657876SArnaldo Carvalho de Melo 		dump_stack();
10987c657876SArnaldo Carvalho de Melo 		break;
10997c657876SArnaldo Carvalho de Melo 	}
11007c657876SArnaldo Carvalho de Melo }
11017c657876SArnaldo Carvalho de Melo 
11027c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
11037c657876SArnaldo Carvalho de Melo {
11047c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
11057c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
11067c657876SArnaldo Carvalho de Melo 	struct ccid3_options_received *opt_recv;
11078c60f3faSArnaldo Carvalho de Melo 	struct dccp_tx_hist_entry *packet;
11087c657876SArnaldo Carvalho de Melo 	unsigned long next_tmout;
11091bc09869SIan McDonald 	u32 t_elapsed;
11107c657876SArnaldo Carvalho de Melo 	u32 pinv;
11117c657876SArnaldo Carvalho de Melo 	u32 x_recv;
11127c657876SArnaldo Carvalho de Melo 	u32 r_sample;
11131f2333aeSArnaldo Carvalho de Melo 
11147c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
11157c657876SArnaldo Carvalho de Melo 		return;
11167c657876SArnaldo Carvalho de Melo 
11177c657876SArnaldo Carvalho de Melo 	if (hctx->ccid3hctx_state == TFRC_SSTATE_TERM) {
11181f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, received a packet when "
11191f2333aeSArnaldo Carvalho de Melo 			       "terminating!\n", dccp_role(sk), sk);
11207c657876SArnaldo Carvalho de Melo 		return;
11217c657876SArnaldo Carvalho de Melo 	}
11227c657876SArnaldo Carvalho de Melo 
11237c657876SArnaldo Carvalho de Melo 	/* we are only interested in ACKs */
11247c657876SArnaldo Carvalho de Melo 	if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
11257c657876SArnaldo Carvalho de Melo 	      DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
11267c657876SArnaldo Carvalho de Melo 		return;
11277c657876SArnaldo Carvalho de Melo 
11287c657876SArnaldo Carvalho de Melo 	opt_recv = &hctx->ccid3hctx_options_received;
11297c657876SArnaldo Carvalho de Melo 
11307c657876SArnaldo Carvalho de Melo 	t_elapsed = dp->dccps_options_received.dccpor_elapsed_time;
11317c657876SArnaldo Carvalho de Melo 	x_recv = opt_recv->ccid3or_receive_rate;
11327c657876SArnaldo Carvalho de Melo 	pinv = opt_recv->ccid3or_loss_event_rate;
11337c657876SArnaldo Carvalho de Melo 
11347c657876SArnaldo Carvalho de Melo 	switch (hctx->ccid3hctx_state) {
11357c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_SENT:
11367c657876SArnaldo Carvalho de Melo 		/* FIXME: what to do here? */
11377c657876SArnaldo Carvalho de Melo 		return;
11387c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_NO_FBACK:
11397c657876SArnaldo Carvalho de Melo 	case TFRC_SSTATE_FBACK:
11407c657876SArnaldo Carvalho de Melo 		/* Calculate new round trip sample by
11417c657876SArnaldo Carvalho de Melo 		 * R_sample = (now - t_recvdata) - t_delay */
11427c657876SArnaldo Carvalho de Melo 		/* get t_recvdata from history */
11438c60f3faSArnaldo Carvalho de Melo 		packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
11448c60f3faSArnaldo Carvalho de Melo 						 DCCP_SKB_CB(skb)->dccpd_ack_seq);
11457c657876SArnaldo Carvalho de Melo 		if (packet == NULL) {
11461f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, seqno %llu(%s) does't "
11471f2333aeSArnaldo Carvalho de Melo 				       "exist in history!\n",
11481f2333aeSArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
11491f2333aeSArnaldo Carvalho de Melo 				       DCCP_SKB_CB(skb)->dccpd_ack_seq,
11507c657876SArnaldo Carvalho de Melo 				       dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
11517c657876SArnaldo Carvalho de Melo 			return;
11527c657876SArnaldo Carvalho de Melo 		}
11537c657876SArnaldo Carvalho de Melo 
11547c657876SArnaldo Carvalho de Melo 		/* Update RTT */
1155b6ee3d4aSArnaldo Carvalho de Melo 		r_sample = timeval_now_delta(&packet->dccphtx_tstamp);
11567c657876SArnaldo Carvalho de Melo 		/* FIXME: */
11577c657876SArnaldo Carvalho de Melo 		// r_sample -= usecs_to_jiffies(t_elapsed * 10);
11587c657876SArnaldo Carvalho de Melo 
11597c657876SArnaldo Carvalho de Melo 		/* Update RTT estimate by
11607c657876SArnaldo Carvalho de Melo 		 * If (No feedback recv)
11617c657876SArnaldo Carvalho de Melo 		 *    R = R_sample;
11627c657876SArnaldo Carvalho de Melo 		 * Else
11637c657876SArnaldo Carvalho de Melo 		 *    R = q * R + (1 - q) * R_sample;
11647c657876SArnaldo Carvalho de Melo 		 *
11657c657876SArnaldo Carvalho de Melo 		 * q is a constant, RFC 3448 recomments 0.9
11667c657876SArnaldo Carvalho de Melo 		 */
11677c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
11687c657876SArnaldo Carvalho de Melo 			ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
11697c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = r_sample;
11707c657876SArnaldo Carvalho de Melo 		} else
11711f2333aeSArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
11721f2333aeSArnaldo Carvalho de Melo 					      r_sample / 10;
11737c657876SArnaldo Carvalho de Melo 
11747c657876SArnaldo Carvalho de Melo 		/*
11757c657876SArnaldo Carvalho de Melo 		 * XXX: this is to avoid a division by zero in ccid3_hc_tx_packet_sent
11767c657876SArnaldo Carvalho de Melo 		 *      implemention of the new window count.
11777c657876SArnaldo Carvalho de Melo 		 */
11787c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_rtt < 4)
11797c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_rtt = 4;
11807c657876SArnaldo Carvalho de Melo 
11811f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, "
11821f2333aeSArnaldo Carvalho de Melo 			       "r_sample=%us\n", dccp_role(sk), sk,
11831f2333aeSArnaldo Carvalho de Melo 			       hctx->ccid3hctx_rtt, r_sample);
11847c657876SArnaldo Carvalho de Melo 
11857c657876SArnaldo Carvalho de Melo 		/* Update timeout interval */
1186c68e64cfSArnaldo Carvalho de Melo 		hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
1187cef07fd6SArnaldo Carvalho de Melo 					      USEC_PER_SEC);
11887c657876SArnaldo Carvalho de Melo 
11897c657876SArnaldo Carvalho de Melo 		/* Update receive rate */
11901f2333aeSArnaldo Carvalho de Melo 		hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
11917c657876SArnaldo Carvalho de Melo 
11927c657876SArnaldo Carvalho de Melo 		/* Update loss event rate */
11937c657876SArnaldo Carvalho de Melo 		if (pinv == ~0 || pinv == 0)
11947c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_p = 0;
11957c657876SArnaldo Carvalho de Melo 		else {
11967c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_p = 1000000 / pinv;
11977c657876SArnaldo Carvalho de Melo 
11987c657876SArnaldo Carvalho de Melo 			if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) {
11997c657876SArnaldo Carvalho de Melo 				hctx->ccid3hctx_p = TFRC_SMALLEST_P;
12001f2333aeSArnaldo Carvalho de Melo 				ccid3_pr_debug("%s, sk=%p, Smallest p used!\n",
12011f2333aeSArnaldo Carvalho de Melo 					       dccp_role(sk), sk);
12027c657876SArnaldo Carvalho de Melo 			}
12037c657876SArnaldo Carvalho de Melo 		}
12047c657876SArnaldo Carvalho de Melo 
12057c657876SArnaldo Carvalho de Melo 		/* unschedule no feedback timer */
12067c657876SArnaldo Carvalho de Melo 		sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
12077c657876SArnaldo Carvalho de Melo 
12087c657876SArnaldo Carvalho de Melo 		/* Update sending rate */
12097c657876SArnaldo Carvalho de Melo 		ccid3_hc_tx_update_x(sk);
12107c657876SArnaldo Carvalho de Melo 
12117c657876SArnaldo Carvalho de Melo 		/* Update next send time */
1212b6ee3d4aSArnaldo Carvalho de Melo 		timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
1213b6ee3d4aSArnaldo Carvalho de Melo 				  hctx->ccid3hctx_t_ipi);
12147c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_t_ipi(hctx);
1215b6ee3d4aSArnaldo Carvalho de Melo 		timeval_add_usecs(&hctx->ccid3hctx_t_nom,
1216b6ee3d4aSArnaldo Carvalho de Melo 				  hctx->ccid3hctx_t_ipi);
12177c657876SArnaldo Carvalho de Melo 		ccid3_calc_new_delta(hctx);
12187c657876SArnaldo Carvalho de Melo 
12197c657876SArnaldo Carvalho de Melo 		/* remove all packets older than the one acked from history */
12208c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_purge_older(ccid3_tx_hist,
12218c60f3faSArnaldo Carvalho de Melo 					 &hctx->ccid3hctx_hist, packet);
12228c60f3faSArnaldo Carvalho de Melo 
12237c657876SArnaldo Carvalho de Melo 		if (hctx->ccid3hctx_x < 10) {
12241f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("ccid3_hc_tx_packet_recv hctx_x < 10\n");
12257c657876SArnaldo Carvalho de Melo 			hctx->ccid3hctx_x = 10;
12267c657876SArnaldo Carvalho de Melo 		}
12277c657876SArnaldo Carvalho de Melo 		/* to prevent divide by zero below */
12287c657876SArnaldo Carvalho de Melo 
12291f2333aeSArnaldo Carvalho de Melo 		/*
12301f2333aeSArnaldo Carvalho de Melo 		 * Schedule no feedback timer to expire in
12311f2333aeSArnaldo Carvalho de Melo 		 * max(4 * R, 2 * s / X)
12321f2333aeSArnaldo Carvalho de Melo 		 */
1233c68e64cfSArnaldo Carvalho de Melo 		next_tmout = max(hctx->ccid3hctx_t_rto,
12348c60f3faSArnaldo Carvalho de Melo 				 (2 * (hctx->ccid3hctx_s * 100000) /
12358c60f3faSArnaldo Carvalho de Melo 				  (hctx->ccid3hctx_x / 10)));
12367c657876SArnaldo Carvalho de Melo 		/* maths with 100000 and 10 is to prevent overflow with 32 bit */
12377c657876SArnaldo Carvalho de Melo 
12381f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
12391f2333aeSArnaldo Carvalho de Melo 			       "expire in %lu jiffies (%luus)\n",
12401f2333aeSArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
12411f2333aeSArnaldo Carvalho de Melo 			       usecs_to_jiffies(next_tmout), next_tmout);
12427c657876SArnaldo Carvalho de Melo 
12437c657876SArnaldo Carvalho de Melo 		sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
12447c657876SArnaldo Carvalho de Melo 			       jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
12457c657876SArnaldo Carvalho de Melo 
12467c657876SArnaldo Carvalho de Melo 		/* set idle flag */
12477c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_idle = 1;
12487c657876SArnaldo Carvalho de Melo 		break;
12497c657876SArnaldo Carvalho de Melo 	default:
12507c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
12517c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
12527c657876SArnaldo Carvalho de Melo 		dump_stack();
12537c657876SArnaldo Carvalho de Melo 		break;
12547c657876SArnaldo Carvalho de Melo 	}
12557c657876SArnaldo Carvalho de Melo }
12567c657876SArnaldo Carvalho de Melo 
12577c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
12587c657876SArnaldo Carvalho de Melo {
12597c657876SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
12607c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
12617c657876SArnaldo Carvalho de Melo 
12621f2333aeSArnaldo Carvalho de Melo 	if (hctx == NULL || !(sk->sk_state == DCCP_OPEN ||
12631f2333aeSArnaldo Carvalho de Melo 			      sk->sk_state == DCCP_PARTOPEN))
12647c657876SArnaldo Carvalho de Melo 		return;
12657c657876SArnaldo Carvalho de Melo 
12667c657876SArnaldo Carvalho de Melo 	 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
12677c657876SArnaldo Carvalho de Melo }
12687c657876SArnaldo Carvalho de Melo 
12697c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
12701f2333aeSArnaldo Carvalho de Melo 				     unsigned char len, u16 idx,
12711f2333aeSArnaldo Carvalho de Melo 				     unsigned char *value)
12727c657876SArnaldo Carvalho de Melo {
12737c657876SArnaldo Carvalho de Melo 	int rc = 0;
12747c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
12757c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
12767c657876SArnaldo Carvalho de Melo 	struct ccid3_options_received *opt_recv;
12777c657876SArnaldo Carvalho de Melo 
12787c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
12797c657876SArnaldo Carvalho de Melo 		return 0;
12807c657876SArnaldo Carvalho de Melo 
12817c657876SArnaldo Carvalho de Melo 	opt_recv = &hctx->ccid3hctx_options_received;
12827c657876SArnaldo Carvalho de Melo 
12837c657876SArnaldo Carvalho de Melo 	if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
12847c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_seqno		     = dp->dccps_gsr;
12857c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_event_rate    = ~0;
12867c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_idx = 0;
12877c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_len = 0;
12887c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_receive_rate	     = 0;
12897c657876SArnaldo Carvalho de Melo 	}
12907c657876SArnaldo Carvalho de Melo 
12917c657876SArnaldo Carvalho de Melo 	switch (option) {
12927c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_LOSS_EVENT_RATE:
12937c657876SArnaldo Carvalho de Melo 		if (len != 4) {
12941f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, invalid len for "
12951f2333aeSArnaldo Carvalho de Melo 				       "TFRC_OPT_LOSS_EVENT_RATE\n",
12967c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
12977c657876SArnaldo Carvalho de Melo 			rc = -EINVAL;
12987c657876SArnaldo Carvalho de Melo 		} else {
12997c657876SArnaldo Carvalho de Melo 			opt_recv->ccid3or_loss_event_rate = ntohl(*(u32 *)value);
13007c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n",
13017c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
13027c657876SArnaldo Carvalho de Melo 				       opt_recv->ccid3or_loss_event_rate);
13037c657876SArnaldo Carvalho de Melo 		}
13047c657876SArnaldo Carvalho de Melo 		break;
13057c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_LOSS_INTERVALS:
13067c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_idx = idx;
13077c657876SArnaldo Carvalho de Melo 		opt_recv->ccid3or_loss_intervals_len = len;
13087c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n",
13097c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
13107c657876SArnaldo Carvalho de Melo 			       opt_recv->ccid3or_loss_intervals_idx,
13117c657876SArnaldo Carvalho de Melo 			       opt_recv->ccid3or_loss_intervals_len);
13127c657876SArnaldo Carvalho de Melo 		break;
13137c657876SArnaldo Carvalho de Melo 	case TFRC_OPT_RECEIVE_RATE:
13147c657876SArnaldo Carvalho de Melo 		if (len != 4) {
13151f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, invalid len for "
13161f2333aeSArnaldo Carvalho de Melo 				       "TFRC_OPT_RECEIVE_RATE\n",
13177c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
13187c657876SArnaldo Carvalho de Melo 			rc = -EINVAL;
13197c657876SArnaldo Carvalho de Melo 		} else {
13207c657876SArnaldo Carvalho de Melo 			opt_recv->ccid3or_receive_rate = ntohl(*(u32 *)value);
13217c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n",
13227c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk,
13237c657876SArnaldo Carvalho de Melo 				       opt_recv->ccid3or_receive_rate);
13247c657876SArnaldo Carvalho de Melo 		}
13257c657876SArnaldo Carvalho de Melo 		break;
13267c657876SArnaldo Carvalho de Melo 	}
13277c657876SArnaldo Carvalho de Melo 
13287c657876SArnaldo Carvalho de Melo 	return rc;
13297c657876SArnaldo Carvalho de Melo }
13307c657876SArnaldo Carvalho de Melo 
13317c657876SArnaldo Carvalho de Melo static int ccid3_hc_tx_init(struct sock *sk)
13327c657876SArnaldo Carvalho de Melo {
13337c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13347c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx;
13357c657876SArnaldo Carvalho de Melo 
13367c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
13377c657876SArnaldo Carvalho de Melo 
13381f2333aeSArnaldo Carvalho de Melo 	hctx = dp->dccps_hc_tx_ccid_private = kmalloc(sizeof(*hctx),
13391f2333aeSArnaldo Carvalho de Melo 						      gfp_any());
13407c657876SArnaldo Carvalho de Melo 	if (hctx == NULL)
13417c657876SArnaldo Carvalho de Melo 		return -ENOMEM;
13427c657876SArnaldo Carvalho de Melo 
13437c657876SArnaldo Carvalho de Melo 	memset(hctx, 0, sizeof(*hctx));
13447c657876SArnaldo Carvalho de Melo 
13457c657876SArnaldo Carvalho de Melo 	if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
13467c657876SArnaldo Carvalho de Melo 	    dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
13477c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_s = (u16)dp->dccps_avg_packet_size;
13487c657876SArnaldo Carvalho de Melo 	else
13497c657876SArnaldo Carvalho de Melo 		hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
13507c657876SArnaldo Carvalho de Melo 
13511f2333aeSArnaldo Carvalho de Melo 	/* Set transmission rate to 1 packet per second */
13521f2333aeSArnaldo Carvalho de Melo 	hctx->ccid3hctx_x     = hctx->ccid3hctx_s;
13531f2333aeSArnaldo Carvalho de Melo 	/* See ccid3_hc_tx_packet_sent win_count calculatation */
13541f2333aeSArnaldo Carvalho de Melo 	hctx->ccid3hctx_rtt   = 4;
1355c68e64cfSArnaldo Carvalho de Melo 	hctx->ccid3hctx_t_rto = USEC_PER_SEC;
13567c657876SArnaldo Carvalho de Melo 	hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
13577c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
13587c657876SArnaldo Carvalho de Melo 	init_timer(&hctx->ccid3hctx_no_feedback_timer);
13597c657876SArnaldo Carvalho de Melo 
13607c657876SArnaldo Carvalho de Melo 	return 0;
13617c657876SArnaldo Carvalho de Melo }
13627c657876SArnaldo Carvalho de Melo 
13637c657876SArnaldo Carvalho de Melo static void ccid3_hc_tx_exit(struct sock *sk)
13647c657876SArnaldo Carvalho de Melo {
13657c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
13667c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
13677c657876SArnaldo Carvalho de Melo 
13687c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
13697c657876SArnaldo Carvalho de Melo 	BUG_ON(hctx == NULL);
13707c657876SArnaldo Carvalho de Melo 
13717c657876SArnaldo Carvalho de Melo 	ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
13727c657876SArnaldo Carvalho de Melo 	sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
13737c657876SArnaldo Carvalho de Melo 
13747c657876SArnaldo Carvalho de Melo 	/* Empty packet history */
13758c60f3faSArnaldo Carvalho de Melo 	dccp_tx_hist_purge(ccid3_tx_hist, &hctx->ccid3hctx_hist);
13767c657876SArnaldo Carvalho de Melo 
13777c657876SArnaldo Carvalho de Melo 	kfree(dp->dccps_hc_tx_ccid_private);
13787c657876SArnaldo Carvalho de Melo 	dp->dccps_hc_tx_ccid_private = NULL;
13797c657876SArnaldo Carvalho de Melo }
13807c657876SArnaldo Carvalho de Melo 
13817c657876SArnaldo Carvalho de Melo /*
13827c657876SArnaldo Carvalho de Melo  * RX Half Connection methods
13837c657876SArnaldo Carvalho de Melo  */
13847c657876SArnaldo Carvalho de Melo 
13857c657876SArnaldo Carvalho de Melo /* TFRC receiver states */
13867c657876SArnaldo Carvalho de Melo enum ccid3_hc_rx_states {
13877c657876SArnaldo Carvalho de Melo        	TFRC_RSTATE_NO_DATA = 1,
13887c657876SArnaldo Carvalho de Melo 	TFRC_RSTATE_DATA,
13897c657876SArnaldo Carvalho de Melo 	TFRC_RSTATE_TERM    = 127,
13907c657876SArnaldo Carvalho de Melo };
13917c657876SArnaldo Carvalho de Melo 
13927c657876SArnaldo Carvalho de Melo #ifdef CCID3_DEBUG
13937c657876SArnaldo Carvalho de Melo static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
13947c657876SArnaldo Carvalho de Melo {
13957c657876SArnaldo Carvalho de Melo 	static char *ccid3_rx_state_names[] = {
13967c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_NO_DATA] = "NO_DATA",
13977c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_DATA]    = "DATA",
13987c657876SArnaldo Carvalho de Melo 	[TFRC_RSTATE_TERM]    = "TERM",
13997c657876SArnaldo Carvalho de Melo 	};
14007c657876SArnaldo Carvalho de Melo 
14017c657876SArnaldo Carvalho de Melo 	return ccid3_rx_state_names[state];
14027c657876SArnaldo Carvalho de Melo }
14037c657876SArnaldo Carvalho de Melo #endif
14047c657876SArnaldo Carvalho de Melo 
14051f2333aeSArnaldo Carvalho de Melo static inline void ccid3_hc_rx_set_state(struct sock *sk,
14061f2333aeSArnaldo Carvalho de Melo 					 enum ccid3_hc_rx_states state)
14077c657876SArnaldo Carvalho de Melo {
14087c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
14097c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
14107c657876SArnaldo Carvalho de Melo 	enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
14117c657876SArnaldo Carvalho de Melo 
14127c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
14131f2333aeSArnaldo Carvalho de Melo 		       dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
14141f2333aeSArnaldo Carvalho de Melo 		       ccid3_rx_state_name(state));
14157c657876SArnaldo Carvalho de Melo 	WARN_ON(state == oldstate);
14167c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_state = state;
14177c657876SArnaldo Carvalho de Melo }
14187c657876SArnaldo Carvalho de Melo 
14198c60f3faSArnaldo Carvalho de Melo static int ccid3_hc_rx_add_hist(struct sock *sk,
14208c60f3faSArnaldo Carvalho de Melo 				struct dccp_rx_hist_entry *packet)
14217c657876SArnaldo Carvalho de Melo {
14227c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
14237c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
14248c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *iter;
14257c657876SArnaldo Carvalho de Melo 	u8 num_later = 0;
14267c657876SArnaldo Carvalho de Melo 
14278c60f3faSArnaldo Carvalho de Melo 	iter = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
14288c60f3faSArnaldo Carvalho de Melo 	if (iter == NULL)
14298c60f3faSArnaldo Carvalho de Melo 		dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
14307c657876SArnaldo Carvalho de Melo 	else {
14318c60f3faSArnaldo Carvalho de Melo 		const u64 seqno = packet->dccphrx_seqno;
14328c60f3faSArnaldo Carvalho de Melo 
14338c60f3faSArnaldo Carvalho de Melo 		if (after48(seqno, iter->dccphrx_seqno))
14348c60f3faSArnaldo Carvalho de Melo 			dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist, packet);
14357c657876SArnaldo Carvalho de Melo 		else {
14368c60f3faSArnaldo Carvalho de Melo 			if (dccp_rx_hist_entry_data_packet(iter))
14377c657876SArnaldo Carvalho de Melo 				num_later = 1;
14387c657876SArnaldo Carvalho de Melo 
14398c60f3faSArnaldo Carvalho de Melo 			list_for_each_entry_continue(iter,
14408c60f3faSArnaldo Carvalho de Melo 						     &hcrx->ccid3hcrx_hist,
14418c60f3faSArnaldo Carvalho de Melo 						     dccphrx_node) {
14428c60f3faSArnaldo Carvalho de Melo 				if (after48(seqno, iter->dccphrx_seqno)) {
14438c60f3faSArnaldo Carvalho de Melo 					dccp_rx_hist_add_entry(&iter->dccphrx_node,
14448c60f3faSArnaldo Carvalho de Melo 							       packet);
14457c657876SArnaldo Carvalho de Melo 					goto trim_history;
14467c657876SArnaldo Carvalho de Melo 				}
14477c657876SArnaldo Carvalho de Melo 
14488c60f3faSArnaldo Carvalho de Melo 				if (dccp_rx_hist_entry_data_packet(iter))
14497c657876SArnaldo Carvalho de Melo 					num_later++;
14507c657876SArnaldo Carvalho de Melo 
14517c657876SArnaldo Carvalho de Melo 				if (num_later == TFRC_RECV_NUM_LATE_LOSS) {
14521f2333aeSArnaldo Carvalho de Melo 					dccp_rx_hist_entry_delete(ccid3_rx_hist,
14531f2333aeSArnaldo Carvalho de Melo 								  packet);
14541f2333aeSArnaldo Carvalho de Melo 					ccid3_pr_debug("%s, sk=%p, packet"
14551f2333aeSArnaldo Carvalho de Melo 						       "(%llu) already lost!\n",
14561f2333aeSArnaldo Carvalho de Melo 						       dccp_role(sk), sk,
14571f2333aeSArnaldo Carvalho de Melo 						       seqno);
14587c657876SArnaldo Carvalho de Melo 					return 1;
14597c657876SArnaldo Carvalho de Melo 				}
14607c657876SArnaldo Carvalho de Melo 			}
14617c657876SArnaldo Carvalho de Melo 
14627c657876SArnaldo Carvalho de Melo 			if (num_later < TFRC_RECV_NUM_LATE_LOSS)
14638c60f3faSArnaldo Carvalho de Melo 				dccp_rx_hist_add_entry(&hcrx->ccid3hcrx_hist,
14648c60f3faSArnaldo Carvalho de Melo 						       packet);
14651f2333aeSArnaldo Carvalho de Melo 			/*
14661f2333aeSArnaldo Carvalho de Melo 			 * FIXME: else what? should we destroy the packet
14671f2333aeSArnaldo Carvalho de Melo 			 * like above?
14681f2333aeSArnaldo Carvalho de Melo 			 */
14697c657876SArnaldo Carvalho de Melo 		}
14707c657876SArnaldo Carvalho de Melo 	}
14717c657876SArnaldo Carvalho de Melo 
14727c657876SArnaldo Carvalho de Melo trim_history:
14731f2333aeSArnaldo Carvalho de Melo 	/*
14741f2333aeSArnaldo Carvalho de Melo 	 * Trim history (remove all packets after the NUM_LATE_LOSS + 1
14751f2333aeSArnaldo Carvalho de Melo 	 * data packets)
14761f2333aeSArnaldo Carvalho de Melo 	 */
14777c657876SArnaldo Carvalho de Melo 	num_later = TFRC_RECV_NUM_LATE_LOSS + 1;
14787c657876SArnaldo Carvalho de Melo 
14797c657876SArnaldo Carvalho de Melo 	if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
14808c60f3faSArnaldo Carvalho de Melo 		list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
14818c60f3faSArnaldo Carvalho de Melo 					 dccphrx_node) {
14827c657876SArnaldo Carvalho de Melo 			if (num_later == 0) {
14838c60f3faSArnaldo Carvalho de Melo 				list_del_init(&entry->dccphrx_node);
14848c60f3faSArnaldo Carvalho de Melo 				dccp_rx_hist_entry_delete(ccid3_rx_hist, entry);
14858c60f3faSArnaldo Carvalho de Melo 			} else if (dccp_rx_hist_entry_data_packet(entry))
14867c657876SArnaldo Carvalho de Melo 				--num_later;
14877c657876SArnaldo Carvalho de Melo 		}
14887c657876SArnaldo Carvalho de Melo 	} else {
14897c657876SArnaldo Carvalho de Melo 		int step = 0;
14907c657876SArnaldo Carvalho de Melo 		u8 win_count = 0; /* Not needed, but lets shut up gcc */
14917c657876SArnaldo Carvalho de Melo 		int tmp;
14927c657876SArnaldo Carvalho de Melo 		/*
14937c657876SArnaldo Carvalho de Melo 		 * We have no loss interval history so we need at least one
14947c657876SArnaldo Carvalho de Melo 		 * rtt:s of data packets to approximate rtt.
14957c657876SArnaldo Carvalho de Melo 		 */
14968c60f3faSArnaldo Carvalho de Melo 		list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
14978c60f3faSArnaldo Carvalho de Melo 					 dccphrx_node) {
14987c657876SArnaldo Carvalho de Melo 			if (num_later == 0) {
14997c657876SArnaldo Carvalho de Melo 				switch (step) {
15007c657876SArnaldo Carvalho de Melo 				case 0:
15017c657876SArnaldo Carvalho de Melo 					step = 1;
15027c657876SArnaldo Carvalho de Melo 					/* OK, find next data packet */
15037c657876SArnaldo Carvalho de Melo 					num_later = 1;
15047c657876SArnaldo Carvalho de Melo 					break;
15057c657876SArnaldo Carvalho de Melo 				case 1:
15067c657876SArnaldo Carvalho de Melo 					step = 2;
15077c657876SArnaldo Carvalho de Melo 					/* OK, find next data packet */
15087c657876SArnaldo Carvalho de Melo 					num_later = 1;
1509c1734376SArnaldo Carvalho de Melo 					win_count = entry->dccphrx_ccval;
15107c657876SArnaldo Carvalho de Melo 					break;
15117c657876SArnaldo Carvalho de Melo 				case 2:
1512c1734376SArnaldo Carvalho de Melo 					tmp = win_count - entry->dccphrx_ccval;
15137c657876SArnaldo Carvalho de Melo 					if (tmp < 0)
15147c657876SArnaldo Carvalho de Melo 						tmp += TFRC_WIN_COUNT_LIMIT;
15157c657876SArnaldo Carvalho de Melo 					if (tmp > TFRC_WIN_COUNT_PER_RTT + 1) {
15161f2333aeSArnaldo Carvalho de Melo 						/*
15171f2333aeSArnaldo Carvalho de Melo 						 * We have found a packet older
15181f2333aeSArnaldo Carvalho de Melo 						 * than one rtt remove the rest
15191f2333aeSArnaldo Carvalho de Melo 						 */
15207c657876SArnaldo Carvalho de Melo 						step = 3;
15217c657876SArnaldo Carvalho de Melo 					} else /* OK, find next data packet */
15227c657876SArnaldo Carvalho de Melo 						num_later = 1;
15237c657876SArnaldo Carvalho de Melo 					break;
15247c657876SArnaldo Carvalho de Melo 				case 3:
15258c60f3faSArnaldo Carvalho de Melo 					list_del_init(&entry->dccphrx_node);
15261f2333aeSArnaldo Carvalho de Melo 					dccp_rx_hist_entry_delete(ccid3_rx_hist,
15271f2333aeSArnaldo Carvalho de Melo 								  entry);
15287c657876SArnaldo Carvalho de Melo 					break;
15297c657876SArnaldo Carvalho de Melo 				}
15308c60f3faSArnaldo Carvalho de Melo 			} else if (dccp_rx_hist_entry_data_packet(entry))
15317c657876SArnaldo Carvalho de Melo 				--num_later;
15327c657876SArnaldo Carvalho de Melo 		}
15337c657876SArnaldo Carvalho de Melo 	}
15347c657876SArnaldo Carvalho de Melo 
15357c657876SArnaldo Carvalho de Melo 	return 0;
15367c657876SArnaldo Carvalho de Melo }
15377c657876SArnaldo Carvalho de Melo 
15387c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_send_feedback(struct sock *sk)
15397c657876SArnaldo Carvalho de Melo {
15407c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
15417c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
15428c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *packet;
1543b6ee3d4aSArnaldo Carvalho de Melo 	struct timeval now;
15447c657876SArnaldo Carvalho de Melo 
15457c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
15467c657876SArnaldo Carvalho de Melo 
1547b6ee3d4aSArnaldo Carvalho de Melo 	do_gettimeofday(&now);
1548b6ee3d4aSArnaldo Carvalho de Melo 
15497c657876SArnaldo Carvalho de Melo 	switch (hcrx->ccid3hcrx_state) {
15507c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_NO_DATA:
15517c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_x_recv = 0;
15527c657876SArnaldo Carvalho de Melo 		break;
15537c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_DATA: {
1554b6ee3d4aSArnaldo Carvalho de Melo 		const u32 delta = timeval_delta(&now,
1555b6ee3d4aSArnaldo Carvalho de Melo 					&hcrx->ccid3hcrx_tstamp_last_feedback);
15567c657876SArnaldo Carvalho de Melo 
1557cef07fd6SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_x_recv = (hcrx->ccid3hcrx_bytes_recv *
1558b6ee3d4aSArnaldo Carvalho de Melo 					  USEC_PER_SEC);
1559b6ee3d4aSArnaldo Carvalho de Melo 		if (likely(delta > 1))
1560b6ee3d4aSArnaldo Carvalho de Melo 			hcrx->ccid3hcrx_x_recv /= delta;
15617c657876SArnaldo Carvalho de Melo 	}
15627c657876SArnaldo Carvalho de Melo 		break;
15637c657876SArnaldo Carvalho de Melo 	default:
15647c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
15657c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
15667c657876SArnaldo Carvalho de Melo 		dump_stack();
15677c657876SArnaldo Carvalho de Melo 		return;
15687c657876SArnaldo Carvalho de Melo 	}
15697c657876SArnaldo Carvalho de Melo 
15708c60f3faSArnaldo Carvalho de Melo 	packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
15717c657876SArnaldo Carvalho de Melo 	if (packet == NULL) {
15727c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, no data packet in history!\n",
15737c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk);
15747c657876SArnaldo Carvalho de Melo 		dump_stack();
15757c657876SArnaldo Carvalho de Melo 		return;
15767c657876SArnaldo Carvalho de Melo 	}
15777c657876SArnaldo Carvalho de Melo 
1578b6ee3d4aSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_tstamp_last_feedback = now;
1579c1734376SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_last_counter	     = packet->dccphrx_ccval;
15808c60f3faSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_seqno_last_counter   = packet->dccphrx_seqno;
15817c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_bytes_recv	     = 0;
15827c657876SArnaldo Carvalho de Melo 
15837c657876SArnaldo Carvalho de Melo 	/* Convert to multiples of 10us */
1584b6ee3d4aSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_elapsed_time =
1585b6ee3d4aSArnaldo Carvalho de Melo 			timeval_delta(&now, &packet->dccphrx_tstamp) / 10;
15867c657876SArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_p == 0)
15877c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_pinv = ~0;
15887c657876SArnaldo Carvalho de Melo 	else
15897c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
15907c657876SArnaldo Carvalho de Melo 	dccp_send_ack(sk);
15917c657876SArnaldo Carvalho de Melo }
15927c657876SArnaldo Carvalho de Melo 
15937c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
15947c657876SArnaldo Carvalho de Melo {
15957c657876SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
15964fded33bSArnaldo Carvalho de Melo 	u32 x_recv, pinv;
15977c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
15987c657876SArnaldo Carvalho de Melo 
15991f2333aeSArnaldo Carvalho de Melo 	if (hcrx == NULL || !(sk->sk_state == DCCP_OPEN ||
16001f2333aeSArnaldo Carvalho de Melo 			      sk->sk_state == DCCP_PARTOPEN))
16017c657876SArnaldo Carvalho de Melo 		return;
16027c657876SArnaldo Carvalho de Melo 
16037c657876SArnaldo Carvalho de Melo 	DCCP_SKB_CB(skb)->dccpd_ccval = hcrx->ccid3hcrx_last_counter;
16044fded33bSArnaldo Carvalho de Melo 
16054fded33bSArnaldo Carvalho de Melo 	if (dccp_packet_without_ack(skb))
16064fded33bSArnaldo Carvalho de Melo 		return;
16074fded33bSArnaldo Carvalho de Melo 
16084fded33bSArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_elapsed_time != 0)
16094fded33bSArnaldo Carvalho de Melo 		dccp_insert_option_elapsed_time(sk, skb,
16104fded33bSArnaldo Carvalho de Melo 						hcrx->ccid3hcrx_elapsed_time);
16114fded33bSArnaldo Carvalho de Melo 	dccp_insert_option_timestamp(sk, skb);
16124fded33bSArnaldo Carvalho de Melo 	x_recv = htonl(hcrx->ccid3hcrx_x_recv);
16134fded33bSArnaldo Carvalho de Melo 	pinv   = htonl(hcrx->ccid3hcrx_pinv);
16144fded33bSArnaldo Carvalho de Melo 	dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
16154fded33bSArnaldo Carvalho de Melo 			   &pinv, sizeof(pinv));
16164fded33bSArnaldo Carvalho de Melo 	dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
16174fded33bSArnaldo Carvalho de Melo 			   &x_recv, sizeof(x_recv));
16187c657876SArnaldo Carvalho de Melo }
16197c657876SArnaldo Carvalho de Melo 
16207c657876SArnaldo Carvalho de Melo /* Weights used to calculate loss event rate */
16217c657876SArnaldo Carvalho de Melo /*
16227c657876SArnaldo Carvalho de Melo  * These are integers as per section 8 of RFC3448. We can then divide by 4 *
16237c657876SArnaldo Carvalho de Melo  * when we use it.
16247c657876SArnaldo Carvalho de Melo  */
1625a1d3a355SArnaldo Carvalho de Melo static const int ccid3_hc_rx_w[TFRC_RECV_IVAL_F_LENGTH] = {
1626a1d3a355SArnaldo Carvalho de Melo 	4, 4, 4, 4, 3, 2, 1, 1,
1627a1d3a355SArnaldo Carvalho de Melo };
16287c657876SArnaldo Carvalho de Melo 
16297c657876SArnaldo Carvalho de Melo /*
16307c657876SArnaldo Carvalho de Melo  * args: fvalue - function value to match
16317c657876SArnaldo Carvalho de Melo  * returns:  p  closest to that value
16327c657876SArnaldo Carvalho de Melo  *
16337c657876SArnaldo Carvalho de Melo  * both fvalue and p are multiplied by 1,000,000 to use ints
16347c657876SArnaldo Carvalho de Melo  */
1635a1d3a355SArnaldo Carvalho de Melo static u32 calcx_reverse_lookup(u32 fvalue) {
16367c657876SArnaldo Carvalho de Melo 	int ctr = 0;
16377c657876SArnaldo Carvalho de Melo 	int small;
16387c657876SArnaldo Carvalho de Melo 
16397c657876SArnaldo Carvalho de Melo 	if (fvalue < calcx_lookup[0][1])
16407c657876SArnaldo Carvalho de Melo 		return 0;
16417c657876SArnaldo Carvalho de Melo 	if (fvalue <= calcx_lookup[CALCX_ARRSIZE-1][1])
16427c657876SArnaldo Carvalho de Melo 		small = 1;
16437c657876SArnaldo Carvalho de Melo 	else if (fvalue > calcx_lookup[CALCX_ARRSIZE-1][0])
16447c657876SArnaldo Carvalho de Melo 		return 1000000;
16457c657876SArnaldo Carvalho de Melo 	else
16467c657876SArnaldo Carvalho de Melo 		small = 0;
16477c657876SArnaldo Carvalho de Melo 	while (fvalue > calcx_lookup[ctr][small])
16487c657876SArnaldo Carvalho de Melo 		ctr++;
16497c657876SArnaldo Carvalho de Melo 	if (small)
16507c657876SArnaldo Carvalho de Melo 		return (CALCX_SPLIT * ctr / CALCX_ARRSIZE);
16517c657876SArnaldo Carvalho de Melo 	else
16527c657876SArnaldo Carvalho de Melo 		return (1000000 * ctr / CALCX_ARRSIZE) ;
16537c657876SArnaldo Carvalho de Melo }
16547c657876SArnaldo Carvalho de Melo 
16557c657876SArnaldo Carvalho de Melo /* calculate first loss interval
16567c657876SArnaldo Carvalho de Melo  *
16577c657876SArnaldo Carvalho de Melo  * returns estimated loss interval in usecs */
16587c657876SArnaldo Carvalho de Melo 
16597c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
16607c657876SArnaldo Carvalho de Melo {
16617c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
16627c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
16638c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
16647c657876SArnaldo Carvalho de Melo 	u32 rtt, delta, x_recv, fval, p, tmp2;
1665b6ee3d4aSArnaldo Carvalho de Melo 	struct timeval tstamp = { 0, };
16667c657876SArnaldo Carvalho de Melo 	int interval = 0;
16677c657876SArnaldo Carvalho de Melo 	int win_count = 0;
16687c657876SArnaldo Carvalho de Melo 	int step = 0;
16697c657876SArnaldo Carvalho de Melo 	u64 tmp1;
16707c657876SArnaldo Carvalho de Melo 
16718c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
16728c60f3faSArnaldo Carvalho de Melo 				 dccphrx_node) {
16738c60f3faSArnaldo Carvalho de Melo 		if (dccp_rx_hist_entry_data_packet(entry)) {
16747c657876SArnaldo Carvalho de Melo 			tail = entry;
16757c657876SArnaldo Carvalho de Melo 
16767c657876SArnaldo Carvalho de Melo 			switch (step) {
16777c657876SArnaldo Carvalho de Melo 			case 0:
16788c60f3faSArnaldo Carvalho de Melo 				tstamp	  = entry->dccphrx_tstamp;
1679c1734376SArnaldo Carvalho de Melo 				win_count = entry->dccphrx_ccval;
16807c657876SArnaldo Carvalho de Melo 				step = 1;
16817c657876SArnaldo Carvalho de Melo 				break;
16827c657876SArnaldo Carvalho de Melo 			case 1:
1683c1734376SArnaldo Carvalho de Melo 				interval = win_count - entry->dccphrx_ccval;
16847c657876SArnaldo Carvalho de Melo 				if (interval < 0)
16857c657876SArnaldo Carvalho de Melo 					interval += TFRC_WIN_COUNT_LIMIT;
16867c657876SArnaldo Carvalho de Melo 				if (interval > 4)
16877c657876SArnaldo Carvalho de Melo 					goto found;
16887c657876SArnaldo Carvalho de Melo 				break;
16897c657876SArnaldo Carvalho de Melo 			}
16907c657876SArnaldo Carvalho de Melo 		}
16917c657876SArnaldo Carvalho de Melo 	}
16927c657876SArnaldo Carvalho de Melo 
16937c657876SArnaldo Carvalho de Melo 	if (step == 0) {
16941f2333aeSArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, packet history contains no "
16951f2333aeSArnaldo Carvalho de Melo 				 "data packets!\n",
16967c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk);
16977c657876SArnaldo Carvalho de Melo 		return ~0;
16987c657876SArnaldo Carvalho de Melo 	}
16997c657876SArnaldo Carvalho de Melo 
17007c657876SArnaldo Carvalho de Melo 	if (interval == 0) {
17011f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Could not find a win_count "
17021f2333aeSArnaldo Carvalho de Melo 			       "interval > 0. Defaulting to 1\n",
17037c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
17047c657876SArnaldo Carvalho de Melo 		interval = 1;
17057c657876SArnaldo Carvalho de Melo 	}
17067c657876SArnaldo Carvalho de Melo found:
1707b6ee3d4aSArnaldo Carvalho de Melo 	rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
17087c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
17097c657876SArnaldo Carvalho de Melo 		       dccp_role(sk), sk, rtt);
17107c657876SArnaldo Carvalho de Melo 	if (rtt == 0)
17117c657876SArnaldo Carvalho de Melo 		rtt = 1;
17127c657876SArnaldo Carvalho de Melo 
1713b6ee3d4aSArnaldo Carvalho de Melo 	delta = timeval_now_delta(&hcrx->ccid3hcrx_tstamp_last_feedback);
1714b6ee3d4aSArnaldo Carvalho de Melo 	x_recv = hcrx->ccid3hcrx_bytes_recv * USEC_PER_SEC;
1715b6ee3d4aSArnaldo Carvalho de Melo 	if (likely(delta > 1))
1716b6ee3d4aSArnaldo Carvalho de Melo 		x_recv /= delta;
17177c657876SArnaldo Carvalho de Melo 
17187c657876SArnaldo Carvalho de Melo 	tmp1 = (u64)x_recv * (u64)rtt;
17197c657876SArnaldo Carvalho de Melo 	do_div(tmp1,10000000);
17207c657876SArnaldo Carvalho de Melo 	tmp2 = (u32)tmp1;
17217c657876SArnaldo Carvalho de Melo 	fval = (hcrx->ccid3hcrx_s * 100000) / tmp2;
17227c657876SArnaldo Carvalho de Melo 	/* do not alter order above or you will get overflow on 32 bit */
17237c657876SArnaldo Carvalho de Melo 	p = calcx_reverse_lookup(fval);
17241f2333aeSArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied "
17251f2333aeSArnaldo Carvalho de Melo 		       "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
17267c657876SArnaldo Carvalho de Melo 
17277c657876SArnaldo Carvalho de Melo 	if (p == 0)
17287c657876SArnaldo Carvalho de Melo 		return ~0;
17297c657876SArnaldo Carvalho de Melo 	else
17307c657876SArnaldo Carvalho de Melo 		return 1000000 / p;
17317c657876SArnaldo Carvalho de Melo }
17327c657876SArnaldo Carvalho de Melo 
17337c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
17347c657876SArnaldo Carvalho de Melo {
17357c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
17367c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
17377c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *li_entry;
17387c657876SArnaldo Carvalho de Melo 
17397c657876SArnaldo Carvalho de Melo 	if (seq_loss != DCCP_MAX_SEQNO + 1) {
17401f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, seq_loss=%llu, win_loss=%u, "
17411f2333aeSArnaldo Carvalho de Melo 			       "packet loss detected\n",
17427c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk, seq_loss, win_loss);
17437c657876SArnaldo Carvalho de Melo 
17447c657876SArnaldo Carvalho de Melo 		if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
17457c657876SArnaldo Carvalho de Melo 			struct ccid3_loss_interval_hist_entry *li_tail = NULL;
17467c657876SArnaldo Carvalho de Melo 			int i;
17477c657876SArnaldo Carvalho de Melo 
17481f2333aeSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, first loss event detected, "
17491f2333aeSArnaldo Carvalho de Melo 				       "creating history\n",
17501f2333aeSArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
17517c657876SArnaldo Carvalho de Melo 			for (i = 0; i <= TFRC_RECV_IVAL_F_LENGTH; ++i) {
17527c657876SArnaldo Carvalho de Melo 				li_entry = ccid3_loss_interval_hist_entry_new(SLAB_ATOMIC);
17537c657876SArnaldo Carvalho de Melo 				if (li_entry == NULL) {
17547c657876SArnaldo Carvalho de Melo 					ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
17551f2333aeSArnaldo Carvalho de Melo 					ccid3_pr_debug("%s, sk=%p, not enough "
17561f2333aeSArnaldo Carvalho de Melo 						       "mem for creating "
17571f2333aeSArnaldo Carvalho de Melo 						       "history\n",
17587c657876SArnaldo Carvalho de Melo 						       dccp_role(sk), sk);
17597c657876SArnaldo Carvalho de Melo 					return;
17607c657876SArnaldo Carvalho de Melo 				}
17617c657876SArnaldo Carvalho de Melo 				if (li_tail == NULL)
17627c657876SArnaldo Carvalho de Melo 					li_tail = li_entry;
17631f2333aeSArnaldo Carvalho de Melo 				list_add(&li_entry->ccid3lih_node,
17641f2333aeSArnaldo Carvalho de Melo 					 &hcrx->ccid3hcrx_loss_interval_hist);
17657c657876SArnaldo Carvalho de Melo 			}
17667c657876SArnaldo Carvalho de Melo 
17677c657876SArnaldo Carvalho de Melo 			li_entry->ccid3lih_seqno     = seq_loss;
17687c657876SArnaldo Carvalho de Melo 			li_entry->ccid3lih_win_count = win_loss;
17697c657876SArnaldo Carvalho de Melo 
17707c657876SArnaldo Carvalho de Melo 			li_tail->ccid3lih_interval   = ccid3_hc_rx_calc_first_li(sk);
17717c657876SArnaldo Carvalho de Melo 		}
17727c657876SArnaldo Carvalho de Melo 	}
17737c657876SArnaldo Carvalho de Melo 	/* FIXME: find end of interval */
17747c657876SArnaldo Carvalho de Melo }
17757c657876SArnaldo Carvalho de Melo 
17767c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_detect_loss(struct sock *sk)
17777c657876SArnaldo Carvalho de Melo {
17787c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
17797c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
17808c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *entry, *next, *packet;
17818c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *a_loss = NULL;
17828c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *b_loss = NULL;
17837c657876SArnaldo Carvalho de Melo 	u64 seq_loss = DCCP_MAX_SEQNO + 1;
17847c657876SArnaldo Carvalho de Melo 	u8 win_loss = 0;
17857c657876SArnaldo Carvalho de Melo 	u8 num_later = TFRC_RECV_NUM_LATE_LOSS;
17867c657876SArnaldo Carvalho de Melo 
17878c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
17888c60f3faSArnaldo Carvalho de Melo 				 dccphrx_node) {
17897c657876SArnaldo Carvalho de Melo 		if (num_later == 0) {
17907c657876SArnaldo Carvalho de Melo 			b_loss = entry;
17917c657876SArnaldo Carvalho de Melo 			break;
17928c60f3faSArnaldo Carvalho de Melo 		} else if (dccp_rx_hist_entry_data_packet(entry))
17937c657876SArnaldo Carvalho de Melo 			--num_later;
17947c657876SArnaldo Carvalho de Melo 	}
17957c657876SArnaldo Carvalho de Melo 
17967c657876SArnaldo Carvalho de Melo 	if (b_loss == NULL)
17977c657876SArnaldo Carvalho de Melo 		goto out_update_li;
17987c657876SArnaldo Carvalho de Melo 
17997c657876SArnaldo Carvalho de Melo 	num_later = 1;
1800757f612eSArnaldo Carvalho de Melo 
18018c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
18028c60f3faSArnaldo Carvalho de Melo 					  dccphrx_node) {
18037c657876SArnaldo Carvalho de Melo 		if (num_later == 0) {
18047c657876SArnaldo Carvalho de Melo 			a_loss = entry;
18057c657876SArnaldo Carvalho de Melo 			break;
18068c60f3faSArnaldo Carvalho de Melo 		} else if (dccp_rx_hist_entry_data_packet(entry))
18077c657876SArnaldo Carvalho de Melo 			--num_later;
18087c657876SArnaldo Carvalho de Melo 	}
18097c657876SArnaldo Carvalho de Melo 
18107c657876SArnaldo Carvalho de Melo 	if (a_loss == NULL) {
18117c657876SArnaldo Carvalho de Melo 		if (list_empty(&hcrx->ccid3hcrx_loss_interval_hist)) {
18127c657876SArnaldo Carvalho de Melo 			/* no loss event have occured yet */
18137c657876SArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, sk=%p, TODO: find a lost data "
18141f2333aeSArnaldo Carvalho de Melo 					"packet by comparing to initial "
18151f2333aeSArnaldo Carvalho de Melo 					"seqno\n",
18167c657876SArnaldo Carvalho de Melo 				       dccp_role(sk), sk);
18177c657876SArnaldo Carvalho de Melo 			goto out_update_li;
18187c657876SArnaldo Carvalho de Melo 		} else {
18191f2333aeSArnaldo Carvalho de Melo 			pr_info("%s: %s, sk=%p, ERROR! Less than 4 data "
18201f2333aeSArnaldo Carvalho de Melo 				"packets in history",
18217c657876SArnaldo Carvalho de Melo 				__FUNCTION__, dccp_role(sk), sk);
18227c657876SArnaldo Carvalho de Melo 			return;
18237c657876SArnaldo Carvalho de Melo 		}
18247c657876SArnaldo Carvalho de Melo 	}
18257c657876SArnaldo Carvalho de Melo 
18267c657876SArnaldo Carvalho de Melo 	/* Locate a lost data packet */
18277c657876SArnaldo Carvalho de Melo 	entry = packet = b_loss;
18288c60f3faSArnaldo Carvalho de Melo 	list_for_each_entry_safe_continue(entry, next, &hcrx->ccid3hcrx_hist,
18298c60f3faSArnaldo Carvalho de Melo 					  dccphrx_node) {
18308c60f3faSArnaldo Carvalho de Melo 		u64 delta = dccp_delta_seqno(entry->dccphrx_seqno,
18318c60f3faSArnaldo Carvalho de Melo 					     packet->dccphrx_seqno);
18327c657876SArnaldo Carvalho de Melo 
18337c657876SArnaldo Carvalho de Melo 		if (delta != 0) {
18348c60f3faSArnaldo Carvalho de Melo 			if (dccp_rx_hist_entry_data_packet(packet))
18357c657876SArnaldo Carvalho de Melo 				--delta;
18367c657876SArnaldo Carvalho de Melo 			/*
18377c657876SArnaldo Carvalho de Melo 			 * FIXME: check this, probably this % usage is because
18387c657876SArnaldo Carvalho de Melo 			 * in earlier drafts the ndp count was just 8 bits
18397c657876SArnaldo Carvalho de Melo 			 * long, but now it cam be up to 24 bits long.
18407c657876SArnaldo Carvalho de Melo 			 */
18417c657876SArnaldo Carvalho de Melo #if 0
18427c657876SArnaldo Carvalho de Melo 			if (delta % DCCP_NDP_LIMIT !=
18438c60f3faSArnaldo Carvalho de Melo 			    (packet->dccphrx_ndp -
18448c60f3faSArnaldo Carvalho de Melo 			     entry->dccphrx_ndp) % DCCP_NDP_LIMIT)
18457c657876SArnaldo Carvalho de Melo #endif
18468c60f3faSArnaldo Carvalho de Melo 			if (delta !=
18478c60f3faSArnaldo Carvalho de Melo 			     packet->dccphrx_ndp - entry->dccphrx_ndp) {
18488c60f3faSArnaldo Carvalho de Melo 				seq_loss = entry->dccphrx_seqno;
18497c657876SArnaldo Carvalho de Melo 				dccp_inc_seqno(&seq_loss);
18507c657876SArnaldo Carvalho de Melo 			}
18517c657876SArnaldo Carvalho de Melo 		}
18527c657876SArnaldo Carvalho de Melo 		packet = entry;
18537c657876SArnaldo Carvalho de Melo 		if (packet == a_loss)
18547c657876SArnaldo Carvalho de Melo 			break;
18557c657876SArnaldo Carvalho de Melo 	}
18567c657876SArnaldo Carvalho de Melo 
18577c657876SArnaldo Carvalho de Melo 	if (seq_loss != DCCP_MAX_SEQNO + 1)
1858c1734376SArnaldo Carvalho de Melo 		win_loss = a_loss->dccphrx_ccval;
18597c657876SArnaldo Carvalho de Melo 
18607c657876SArnaldo Carvalho de Melo out_update_li:
18617c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_update_li(sk, seq_loss, win_loss);
18627c657876SArnaldo Carvalho de Melo }
18637c657876SArnaldo Carvalho de Melo 
18647c657876SArnaldo Carvalho de Melo static u32 ccid3_hc_rx_calc_i_mean(struct sock *sk)
18657c657876SArnaldo Carvalho de Melo {
18667c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
18677c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
18687c657876SArnaldo Carvalho de Melo 	struct ccid3_loss_interval_hist_entry *li_entry, *li_next;
18697c657876SArnaldo Carvalho de Melo 	int i = 0;
18707c657876SArnaldo Carvalho de Melo 	u32 i_tot;
18717c657876SArnaldo Carvalho de Melo 	u32 i_tot0 = 0;
18727c657876SArnaldo Carvalho de Melo 	u32 i_tot1 = 0;
18737c657876SArnaldo Carvalho de Melo 	u32 w_tot  = 0;
18747c657876SArnaldo Carvalho de Melo 
18751f2333aeSArnaldo Carvalho de Melo 	list_for_each_entry_safe(li_entry, li_next,
18761f2333aeSArnaldo Carvalho de Melo 				 &hcrx->ccid3hcrx_loss_interval_hist,
18771f2333aeSArnaldo Carvalho de Melo 				 ccid3lih_node) {
18787c657876SArnaldo Carvalho de Melo 		if (i < TFRC_RECV_IVAL_F_LENGTH) {
18797c657876SArnaldo Carvalho de Melo 			i_tot0 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i];
18807c657876SArnaldo Carvalho de Melo 			w_tot  += ccid3_hc_rx_w[i];
18817c657876SArnaldo Carvalho de Melo 		}
18827c657876SArnaldo Carvalho de Melo 
18837c657876SArnaldo Carvalho de Melo 		if (i != 0)
18847c657876SArnaldo Carvalho de Melo 			i_tot1 += li_entry->ccid3lih_interval * ccid3_hc_rx_w[i - 1];
18857c657876SArnaldo Carvalho de Melo 
18867c657876SArnaldo Carvalho de Melo 		if (++i > TFRC_RECV_IVAL_F_LENGTH)
18877c657876SArnaldo Carvalho de Melo 			break;
18887c657876SArnaldo Carvalho de Melo 	}
18897c657876SArnaldo Carvalho de Melo 
18907c657876SArnaldo Carvalho de Melo 	if (i != TFRC_RECV_IVAL_F_LENGTH) {
18911f2333aeSArnaldo Carvalho de Melo 		pr_info("%s: %s, sk=%p, ERROR! Missing entry in "
18921f2333aeSArnaldo Carvalho de Melo 			"interval history!\n",
18937c657876SArnaldo Carvalho de Melo 			__FUNCTION__, dccp_role(sk), sk);
18947c657876SArnaldo Carvalho de Melo 		return 0;
18957c657876SArnaldo Carvalho de Melo 	}
18967c657876SArnaldo Carvalho de Melo 
18977c657876SArnaldo Carvalho de Melo 	i_tot = max(i_tot0, i_tot1);
18987c657876SArnaldo Carvalho de Melo 
18997c657876SArnaldo Carvalho de Melo 	/* FIXME: Why do we do this? -Ian McDonald */
19007c657876SArnaldo Carvalho de Melo 	if (i_tot * 4 < w_tot)
19017c657876SArnaldo Carvalho de Melo 		i_tot = w_tot * 4;
19027c657876SArnaldo Carvalho de Melo 
19037c657876SArnaldo Carvalho de Melo 	return i_tot * 4 / w_tot;
19047c657876SArnaldo Carvalho de Melo }
19057c657876SArnaldo Carvalho de Melo 
19067c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
19077c657876SArnaldo Carvalho de Melo {
19087c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
19097c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
19104fded33bSArnaldo Carvalho de Melo 	const struct dccp_options_received *opt_recv;
19118c60f3faSArnaldo Carvalho de Melo 	struct dccp_rx_hist_entry *packet;
19127c657876SArnaldo Carvalho de Melo 	struct timeval now;
19137c657876SArnaldo Carvalho de Melo 	u8 win_count;
19147c657876SArnaldo Carvalho de Melo 	u32 p_prev;
19157c657876SArnaldo Carvalho de Melo 	int ins;
19161f2333aeSArnaldo Carvalho de Melo 
19177c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
19187c657876SArnaldo Carvalho de Melo 		return;
19197c657876SArnaldo Carvalho de Melo 
19207c657876SArnaldo Carvalho de Melo 	BUG_ON(!(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
19217c657876SArnaldo Carvalho de Melo 		 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
19227c657876SArnaldo Carvalho de Melo 
19234fded33bSArnaldo Carvalho de Melo 	opt_recv = &dp->dccps_options_received;
19244fded33bSArnaldo Carvalho de Melo 
19257c657876SArnaldo Carvalho de Melo 	switch (DCCP_SKB_CB(skb)->dccpd_type) {
19267c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_ACK:
19277c657876SArnaldo Carvalho de Melo 		if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
19287c657876SArnaldo Carvalho de Melo 			return;
19297c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_DATAACK:
19304fded33bSArnaldo Carvalho de Melo 		if (opt_recv->dccpor_timestamp_echo == 0)
19317c657876SArnaldo Carvalho de Melo 			break;
19327c657876SArnaldo Carvalho de Melo 		p_prev = hcrx->ccid3hcrx_rtt;
19337c657876SArnaldo Carvalho de Melo 		do_gettimeofday(&now);
1934b6ee3d4aSArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_rtt = timeval_usecs(&now) -
19354fded33bSArnaldo Carvalho de Melo 				     (opt_recv->dccpor_timestamp_echo -
19364fded33bSArnaldo Carvalho de Melo 				      opt_recv->dccpor_elapsed_time) * 10;
19377c657876SArnaldo Carvalho de Melo 		if (p_prev != hcrx->ccid3hcrx_rtt)
19384fded33bSArnaldo Carvalho de Melo 			ccid3_pr_debug("%s, New RTT=%luus, elapsed time=%u\n",
19394fded33bSArnaldo Carvalho de Melo 				       dccp_role(sk), hcrx->ccid3hcrx_rtt,
19404fded33bSArnaldo Carvalho de Melo 				       opt_recv->dccpor_elapsed_time);
19417c657876SArnaldo Carvalho de Melo 		break;
19427c657876SArnaldo Carvalho de Melo 	case DCCP_PKT_DATA:
19437c657876SArnaldo Carvalho de Melo 		break;
19447c657876SArnaldo Carvalho de Melo 	default:
19457c657876SArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, not DATA/DATAACK/ACK packet(%s)\n",
19467c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
19477c657876SArnaldo Carvalho de Melo 			       dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
19487c657876SArnaldo Carvalho de Melo 		return;
19497c657876SArnaldo Carvalho de Melo 	}
19507c657876SArnaldo Carvalho de Melo 
19514fded33bSArnaldo Carvalho de Melo 	packet = dccp_rx_hist_entry_new(ccid3_rx_hist, opt_recv->dccpor_ndp,
19528c60f3faSArnaldo Carvalho de Melo 					skb, SLAB_ATOMIC);
19537c657876SArnaldo Carvalho de Melo 	if (packet == NULL) {
19541f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p, Not enough mem to add rx packet "
19551f2333aeSArnaldo Carvalho de Melo 			       "to history (consider it lost)!",
19567c657876SArnaldo Carvalho de Melo 			       dccp_role(sk), sk);
19577c657876SArnaldo Carvalho de Melo 		return;
19587c657876SArnaldo Carvalho de Melo 	}
19597c657876SArnaldo Carvalho de Melo 
1960c1734376SArnaldo Carvalho de Melo 	win_count = packet->dccphrx_ccval;
19617c657876SArnaldo Carvalho de Melo 
19627c657876SArnaldo Carvalho de Melo 	ins = ccid3_hc_rx_add_hist(sk, packet);
19637c657876SArnaldo Carvalho de Melo 
19647c657876SArnaldo Carvalho de Melo 	if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
19657c657876SArnaldo Carvalho de Melo 		return;
19667c657876SArnaldo Carvalho de Melo 
19677c657876SArnaldo Carvalho de Melo 	switch (hcrx->ccid3hcrx_state) {
19687c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_NO_DATA:
19691f2333aeSArnaldo Carvalho de Melo 		ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial "
19701f2333aeSArnaldo Carvalho de Melo 			       "feedback\n",
19711f2333aeSArnaldo Carvalho de Melo 			       dccp_role(sk), sk,
19721f2333aeSArnaldo Carvalho de Melo 			       dccp_state_name(sk->sk_state), skb);
19737c657876SArnaldo Carvalho de Melo 		ccid3_hc_rx_send_feedback(sk);
19747c657876SArnaldo Carvalho de Melo 		ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
19757c657876SArnaldo Carvalho de Melo 		return;
19767c657876SArnaldo Carvalho de Melo 	case TFRC_RSTATE_DATA:
19771f2333aeSArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_bytes_recv += skb->len -
19781f2333aeSArnaldo Carvalho de Melo 					      dccp_hdr(skb)->dccph_doff * 4;
1979b6ee3d4aSArnaldo Carvalho de Melo 		if (ins != 0)
1980b6ee3d4aSArnaldo Carvalho de Melo 			break;
1981b6ee3d4aSArnaldo Carvalho de Melo 
1982b6ee3d4aSArnaldo Carvalho de Melo 		do_gettimeofday(&now);
1983b6ee3d4aSArnaldo Carvalho de Melo 		if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >=
19844fded33bSArnaldo Carvalho de Melo 		    hcrx->ccid3hcrx_rtt) {
1985b6ee3d4aSArnaldo Carvalho de Melo 			hcrx->ccid3hcrx_tstamp_last_ack = now;
19867c657876SArnaldo Carvalho de Melo 			ccid3_hc_rx_send_feedback(sk);
19877c657876SArnaldo Carvalho de Melo 		}
19887c657876SArnaldo Carvalho de Melo 		return;
19897c657876SArnaldo Carvalho de Melo 	default:
19907c657876SArnaldo Carvalho de Melo 		printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
19917c657876SArnaldo Carvalho de Melo 		       __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
19927c657876SArnaldo Carvalho de Melo 		dump_stack();
19937c657876SArnaldo Carvalho de Melo 		return;
19947c657876SArnaldo Carvalho de Melo 	}
19957c657876SArnaldo Carvalho de Melo 
19967c657876SArnaldo Carvalho de Melo 	/* Dealing with packet loss */
19974fded33bSArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n",
19984fded33bSArnaldo Carvalho de Melo 		       dccp_role(sk), sk, dccp_state_name(sk->sk_state));
19997c657876SArnaldo Carvalho de Melo 
20007c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_detect_loss(sk);
20017c657876SArnaldo Carvalho de Melo 	p_prev = hcrx->ccid3hcrx_p;
20027c657876SArnaldo Carvalho de Melo 
20037c657876SArnaldo Carvalho de Melo 	/* Calculate loss event rate */
20047c657876SArnaldo Carvalho de Melo 	if (!list_empty(&hcrx->ccid3hcrx_loss_interval_hist))
20057c657876SArnaldo Carvalho de Melo 		/* Scaling up by 1000000 as fixed decimal */
20067c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_p = 1000000 / ccid3_hc_rx_calc_i_mean(sk);
20077c657876SArnaldo Carvalho de Melo 
20087c657876SArnaldo Carvalho de Melo 	if (hcrx->ccid3hcrx_p > p_prev) {
20097c657876SArnaldo Carvalho de Melo 		ccid3_hc_rx_send_feedback(sk);
20107c657876SArnaldo Carvalho de Melo 		return;
20117c657876SArnaldo Carvalho de Melo 	}
20127c657876SArnaldo Carvalho de Melo }
20137c657876SArnaldo Carvalho de Melo 
20147c657876SArnaldo Carvalho de Melo static int ccid3_hc_rx_init(struct sock *sk)
20157c657876SArnaldo Carvalho de Melo {
20167c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
20177c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx;
20187c657876SArnaldo Carvalho de Melo 
20197c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
20207c657876SArnaldo Carvalho de Melo 
20211f2333aeSArnaldo Carvalho de Melo 	hcrx = dp->dccps_hc_rx_ccid_private = kmalloc(sizeof(*hcrx),
20221f2333aeSArnaldo Carvalho de Melo 						      gfp_any());
20237c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
20247c657876SArnaldo Carvalho de Melo 		return -ENOMEM;
20257c657876SArnaldo Carvalho de Melo 
20267c657876SArnaldo Carvalho de Melo 	memset(hcrx, 0, sizeof(*hcrx));
20277c657876SArnaldo Carvalho de Melo 
20287c657876SArnaldo Carvalho de Melo 	if (dp->dccps_avg_packet_size >= TFRC_MIN_PACKET_SIZE &&
20297c657876SArnaldo Carvalho de Melo 	    dp->dccps_avg_packet_size <= TFRC_MAX_PACKET_SIZE)
20307c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_s = (u16)dp->dccps_avg_packet_size;
20317c657876SArnaldo Carvalho de Melo 	else
20327c657876SArnaldo Carvalho de Melo 		hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
20337c657876SArnaldo Carvalho de Melo 
20347c657876SArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
20357c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
20367c657876SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&hcrx->ccid3hcrx_loss_interval_hist);
20374fded33bSArnaldo Carvalho de Melo 	/*
20384fded33bSArnaldo Carvalho de Melo 	 * XXX this seems to be paranoid, need to think more about this, for
20394fded33bSArnaldo Carvalho de Melo 	 * now start with something different than zero. -acme
20404fded33bSArnaldo Carvalho de Melo 	 */
20414fded33bSArnaldo Carvalho de Melo 	hcrx->ccid3hcrx_rtt = USEC_PER_SEC / 5;
20427c657876SArnaldo Carvalho de Melo 	return 0;
20437c657876SArnaldo Carvalho de Melo }
20447c657876SArnaldo Carvalho de Melo 
20457c657876SArnaldo Carvalho de Melo static void ccid3_hc_rx_exit(struct sock *sk)
20467c657876SArnaldo Carvalho de Melo {
20477c657876SArnaldo Carvalho de Melo 	struct dccp_sock *dp = dccp_sk(sk);
20487c657876SArnaldo Carvalho de Melo 	struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
20497c657876SArnaldo Carvalho de Melo 
20507c657876SArnaldo Carvalho de Melo 	ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk);
20517c657876SArnaldo Carvalho de Melo 
20527c657876SArnaldo Carvalho de Melo 	if (hcrx == NULL)
20537c657876SArnaldo Carvalho de Melo 		return;
20547c657876SArnaldo Carvalho de Melo 
20557c657876SArnaldo Carvalho de Melo 	ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
20567c657876SArnaldo Carvalho de Melo 
20577c657876SArnaldo Carvalho de Melo 	/* Empty packet history */
20588c60f3faSArnaldo Carvalho de Melo 	dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
20597c657876SArnaldo Carvalho de Melo 
20607c657876SArnaldo Carvalho de Melo 	/* Empty loss interval history */
20617c657876SArnaldo Carvalho de Melo 	ccid3_loss_interval_history_delete(&hcrx->ccid3hcrx_loss_interval_hist);
20627c657876SArnaldo Carvalho de Melo 
20637c657876SArnaldo Carvalho de Melo 	kfree(dp->dccps_hc_rx_ccid_private);
20647c657876SArnaldo Carvalho de Melo 	dp->dccps_hc_rx_ccid_private = NULL;
20657c657876SArnaldo Carvalho de Melo }
20667c657876SArnaldo Carvalho de Melo 
20672babe1f6SArnaldo Carvalho de Melo static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
20682babe1f6SArnaldo Carvalho de Melo {
20692babe1f6SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
20702babe1f6SArnaldo Carvalho de Melo 	const struct ccid3_hc_rx_sock *hcrx = dp->dccps_hc_rx_ccid_private;
20712babe1f6SArnaldo Carvalho de Melo 
20722babe1f6SArnaldo Carvalho de Melo 	if (hcrx == NULL)
20732babe1f6SArnaldo Carvalho de Melo 		return;
20742babe1f6SArnaldo Carvalho de Melo 
20752babe1f6SArnaldo Carvalho de Melo 	info->tcpi_ca_state	= hcrx->ccid3hcrx_state;
20762babe1f6SArnaldo Carvalho de Melo 	info->tcpi_options	|= TCPI_OPT_TIMESTAMPS;
20772babe1f6SArnaldo Carvalho de Melo 	info->tcpi_rcv_rtt	= hcrx->ccid3hcrx_rtt;
20782babe1f6SArnaldo Carvalho de Melo }
20792babe1f6SArnaldo Carvalho de Melo 
20802babe1f6SArnaldo Carvalho de Melo static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
20812babe1f6SArnaldo Carvalho de Melo {
20822babe1f6SArnaldo Carvalho de Melo 	const struct dccp_sock *dp = dccp_sk(sk);
20832babe1f6SArnaldo Carvalho de Melo 	const struct ccid3_hc_tx_sock *hctx = dp->dccps_hc_tx_ccid_private;
20842babe1f6SArnaldo Carvalho de Melo 
20852babe1f6SArnaldo Carvalho de Melo 	if (hctx == NULL)
20862babe1f6SArnaldo Carvalho de Melo 		return;
20872babe1f6SArnaldo Carvalho de Melo 
20882babe1f6SArnaldo Carvalho de Melo 	info->tcpi_rto = hctx->ccid3hctx_t_rto;
20892babe1f6SArnaldo Carvalho de Melo 	info->tcpi_rtt = hctx->ccid3hctx_rtt;
20902babe1f6SArnaldo Carvalho de Melo }
20912babe1f6SArnaldo Carvalho de Melo 
20927c657876SArnaldo Carvalho de Melo static struct ccid ccid3 = {
20937c657876SArnaldo Carvalho de Melo 	.ccid_id		   = 3,
20947c657876SArnaldo Carvalho de Melo 	.ccid_name		   = "ccid3",
20957c657876SArnaldo Carvalho de Melo 	.ccid_owner		   = THIS_MODULE,
20967c657876SArnaldo Carvalho de Melo 	.ccid_init		   = ccid3_init,
20977c657876SArnaldo Carvalho de Melo 	.ccid_exit		   = ccid3_exit,
20987c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_init	   = ccid3_hc_tx_init,
20997c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_exit	   = ccid3_hc_tx_exit,
21007c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_send_packet	   = ccid3_hc_tx_send_packet,
21017c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_packet_sent	   = ccid3_hc_tx_packet_sent,
21027c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_packet_recv	   = ccid3_hc_tx_packet_recv,
21037c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
21047c657876SArnaldo Carvalho de Melo 	.ccid_hc_tx_parse_options  = ccid3_hc_tx_parse_options,
21057c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_init	   = ccid3_hc_rx_init,
21067c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_exit	   = ccid3_hc_rx_exit,
21077c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
21087c657876SArnaldo Carvalho de Melo 	.ccid_hc_rx_packet_recv	   = ccid3_hc_rx_packet_recv,
21092babe1f6SArnaldo Carvalho de Melo 	.ccid_hc_rx_get_info	   = ccid3_hc_rx_get_info,
21102babe1f6SArnaldo Carvalho de Melo 	.ccid_hc_tx_get_info	   = ccid3_hc_tx_get_info,
21117c657876SArnaldo Carvalho de Melo };
21127c657876SArnaldo Carvalho de Melo 
21137c657876SArnaldo Carvalho de Melo module_param(ccid3_debug, int, 0444);
21147c657876SArnaldo Carvalho de Melo MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
21157c657876SArnaldo Carvalho de Melo 
21167c657876SArnaldo Carvalho de Melo static __init int ccid3_module_init(void)
21177c657876SArnaldo Carvalho de Melo {
21188c60f3faSArnaldo Carvalho de Melo 	int rc = -ENOBUFS;
21197c657876SArnaldo Carvalho de Melo 
21208c60f3faSArnaldo Carvalho de Melo 	ccid3_rx_hist = dccp_rx_hist_new("ccid3");
21218c60f3faSArnaldo Carvalho de Melo 	if (ccid3_rx_hist == NULL)
21227c657876SArnaldo Carvalho de Melo 		goto out;
21237c657876SArnaldo Carvalho de Melo 
21248c60f3faSArnaldo Carvalho de Melo 	ccid3_tx_hist = dccp_tx_hist_new("ccid3");
21258c60f3faSArnaldo Carvalho de Melo 	if (ccid3_tx_hist == NULL)
21268c60f3faSArnaldo Carvalho de Melo 		goto out_free_rx;
21277c657876SArnaldo Carvalho de Melo 
21288c60f3faSArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_slab = kmem_cache_create("li_hist_ccid3",
21298c60f3faSArnaldo Carvalho de Melo 				  sizeof(struct ccid3_loss_interval_hist_entry),
21308c60f3faSArnaldo Carvalho de Melo 							  0, SLAB_HWCACHE_ALIGN,
21318c60f3faSArnaldo Carvalho de Melo 							  NULL, NULL);
21327c657876SArnaldo Carvalho de Melo 	if (ccid3_loss_interval_hist_slab == NULL)
21338c60f3faSArnaldo Carvalho de Melo 		goto out_free_tx;
21347c657876SArnaldo Carvalho de Melo 
21357c657876SArnaldo Carvalho de Melo 	rc = ccid_register(&ccid3);
21367c657876SArnaldo Carvalho de Melo 	if (rc != 0)
21377c657876SArnaldo Carvalho de Melo 		goto out_free_loss_interval_history;
21387c657876SArnaldo Carvalho de Melo out:
21397c657876SArnaldo Carvalho de Melo 	return rc;
21408c60f3faSArnaldo Carvalho de Melo 
21417c657876SArnaldo Carvalho de Melo out_free_loss_interval_history:
21427c657876SArnaldo Carvalho de Melo 	kmem_cache_destroy(ccid3_loss_interval_hist_slab);
21437c657876SArnaldo Carvalho de Melo 	ccid3_loss_interval_hist_slab = NULL;
21448c60f3faSArnaldo Carvalho de Melo out_free_tx:
21458c60f3faSArnaldo Carvalho de Melo 	dccp_tx_hist_delete(ccid3_tx_hist);
21468c60f3faSArnaldo Carvalho de Melo 	ccid3_tx_hist = NULL;
21478c60f3faSArnaldo Carvalho de Melo out_free_rx:
21488c60f3faSArnaldo Carvalho de Melo 	dccp_rx_hist_delete(ccid3_rx_hist);
21498c60f3faSArnaldo Carvalho de Melo 	ccid3_rx_hist = NULL;
21507c657876SArnaldo Carvalho de Melo 	goto out;
21517c657876SArnaldo Carvalho de Melo }
21527c657876SArnaldo Carvalho de Melo module_init(ccid3_module_init);
21537c657876SArnaldo Carvalho de Melo 
21547c657876SArnaldo Carvalho de Melo static __exit void ccid3_module_exit(void)
21557c657876SArnaldo Carvalho de Melo {
2156725ba8eeSArnaldo Carvalho de Melo #ifdef CONFIG_IP_DCCP_UNLOAD_HACK
2157725ba8eeSArnaldo Carvalho de Melo 	/*
2158725ba8eeSArnaldo Carvalho de Melo 	 * Hack to use while developing, so that we get rid of the control
2159725ba8eeSArnaldo Carvalho de Melo 	 * sock, that is what keeps a refcount on dccp.ko -acme
2160725ba8eeSArnaldo Carvalho de Melo 	 */
2161725ba8eeSArnaldo Carvalho de Melo 	extern void dccp_ctl_sock_exit(void);
2162725ba8eeSArnaldo Carvalho de Melo 
2163725ba8eeSArnaldo Carvalho de Melo 	dccp_ctl_sock_exit();
2164725ba8eeSArnaldo Carvalho de Melo #endif
21657c657876SArnaldo Carvalho de Melo 	ccid_unregister(&ccid3);
21667c657876SArnaldo Carvalho de Melo 
21678c60f3faSArnaldo Carvalho de Melo 	if (ccid3_tx_hist != NULL) {
21688c60f3faSArnaldo Carvalho de Melo 		dccp_tx_hist_delete(ccid3_tx_hist);
21698c60f3faSArnaldo Carvalho de Melo 		ccid3_tx_hist = NULL;
21707c657876SArnaldo Carvalho de Melo 	}
21718c60f3faSArnaldo Carvalho de Melo 	if (ccid3_rx_hist != NULL) {
21728c60f3faSArnaldo Carvalho de Melo 		dccp_rx_hist_delete(ccid3_rx_hist);
21738c60f3faSArnaldo Carvalho de Melo 		ccid3_rx_hist = NULL;
21747c657876SArnaldo Carvalho de Melo 	}
21757c657876SArnaldo Carvalho de Melo 	if (ccid3_loss_interval_hist_slab != NULL) {
21767c657876SArnaldo Carvalho de Melo 		kmem_cache_destroy(ccid3_loss_interval_hist_slab);
21777c657876SArnaldo Carvalho de Melo 		ccid3_loss_interval_hist_slab = NULL;
21787c657876SArnaldo Carvalho de Melo 	}
21797c657876SArnaldo Carvalho de Melo }
21807c657876SArnaldo Carvalho de Melo module_exit(ccid3_module_exit);
21817c657876SArnaldo Carvalho de Melo 
21821f2333aeSArnaldo Carvalho de Melo MODULE_AUTHOR("Ian McDonald <iam4@cs.waikato.ac.nz>, "
21831f2333aeSArnaldo Carvalho de Melo 	      "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
21847c657876SArnaldo Carvalho de Melo MODULE_DESCRIPTION("DCCP TFRC CCID3 CCID");
21857c657876SArnaldo Carvalho de Melo MODULE_LICENSE("GPL");
21867c657876SArnaldo Carvalho de Melo MODULE_ALIAS("net-dccp-ccid-3");
2187