xref: /OK3568_Linux_fs/kernel/net/dccp/ccids/lib/tfrc.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun #ifndef _TFRC_H_
3*4882a593Smuzhiyun #define _TFRC_H_
4*4882a593Smuzhiyun /*
5*4882a593Smuzhiyun  *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
6*4882a593Smuzhiyun  *  Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
7*4882a593Smuzhiyun  *  Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
8*4882a593Smuzhiyun  *  Copyright (c) 2005   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9*4882a593Smuzhiyun  *  Copyright (c) 2003   Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun #include <linux/types.h>
12*4882a593Smuzhiyun #include <linux/math64.h>
13*4882a593Smuzhiyun #include "../../dccp.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /* internal includes that this library exports: */
16*4882a593Smuzhiyun #include "loss_interval.h"
17*4882a593Smuzhiyun #include "packet_history.h"
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
20*4882a593Smuzhiyun extern bool tfrc_debug;
21*4882a593Smuzhiyun #define tfrc_pr_debug(format, a...)	DCCP_PR_DEBUG(tfrc_debug, format, ##a)
22*4882a593Smuzhiyun #else
23*4882a593Smuzhiyun #define tfrc_pr_debug(format, a...)
24*4882a593Smuzhiyun #endif
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /* integer-arithmetic divisions of type (a * 1000000)/b */
scaled_div(u64 a,u64 b)27*4882a593Smuzhiyun static inline u64 scaled_div(u64 a, u64 b)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	BUG_ON(b == 0);
30*4882a593Smuzhiyun 	return div64_u64(a * 1000000, b);
31*4882a593Smuzhiyun }
32*4882a593Smuzhiyun 
scaled_div32(u64 a,u64 b)33*4882a593Smuzhiyun static inline u32 scaled_div32(u64 a, u64 b)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun 	u64 result = scaled_div(a, b);
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	if (result > UINT_MAX) {
38*4882a593Smuzhiyun 		DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX",
39*4882a593Smuzhiyun 			  (unsigned long long)a, (unsigned long long)b);
40*4882a593Smuzhiyun 		return UINT_MAX;
41*4882a593Smuzhiyun 	}
42*4882a593Smuzhiyun 	return result;
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /**
46*4882a593Smuzhiyun  * tfrc_ewma  -  Exponentially weighted moving average
47*4882a593Smuzhiyun  * @weight: Weight to be used as damping factor, in units of 1/10
48*4882a593Smuzhiyun  */
tfrc_ewma(const u32 avg,const u32 newval,const u8 weight)49*4882a593Smuzhiyun static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun 	return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval;
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun u32 tfrc_calc_x(u16 s, u32 R, u32 p);
55*4882a593Smuzhiyun u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
56*4882a593Smuzhiyun u32 tfrc_invert_loss_event_rate(u32 loss_event_rate);
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun int tfrc_tx_packet_history_init(void);
59*4882a593Smuzhiyun void tfrc_tx_packet_history_exit(void);
60*4882a593Smuzhiyun int tfrc_rx_packet_history_init(void);
61*4882a593Smuzhiyun void tfrc_rx_packet_history_exit(void);
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun int tfrc_li_init(void);
64*4882a593Smuzhiyun void tfrc_li_exit(void);
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #ifdef CONFIG_IP_DCCP_TFRC_LIB
67*4882a593Smuzhiyun int tfrc_lib_init(void);
68*4882a593Smuzhiyun void tfrc_lib_exit(void);
69*4882a593Smuzhiyun #else
70*4882a593Smuzhiyun #define tfrc_lib_init() (0)
71*4882a593Smuzhiyun #define tfrc_lib_exit()
72*4882a593Smuzhiyun #endif
73*4882a593Smuzhiyun #endif /* _TFRC_H_ */
74