1*2874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
236729c1aSArnaldo Carvalho de Melo #ifndef _TFRC_H_
336729c1aSArnaldo Carvalho de Melo #define _TFRC_H_
436729c1aSArnaldo Carvalho de Melo /*
5c40616c5SGerrit Renker * Copyright (c) 2007 The University of Aberdeen, Scotland, UK
6c40616c5SGerrit Renker * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand.
7c40616c5SGerrit Renker * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz>
836729c1aSArnaldo Carvalho de Melo * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
936729c1aSArnaldo Carvalho de Melo * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon
1036729c1aSArnaldo Carvalho de Melo */
1136729c1aSArnaldo Carvalho de Melo #include <linux/types.h>
127deb0f85SGerrit Renker #include <linux/math64.h>
13c40616c5SGerrit Renker #include "../../dccp.h"
14129fa447SGerrit Renker
15129fa447SGerrit Renker /* internal includes that this library exports: */
168a9c7e92SGerrit Renker #include "loss_interval.h"
178a9c7e92SGerrit Renker #include "packet_history.h"
18c40616c5SGerrit Renker
19c40616c5SGerrit Renker #ifdef CONFIG_IP_DCCP_TFRC_DEBUG
2009db3080SGerrit Renker extern bool tfrc_debug;
21c40616c5SGerrit Renker #define tfrc_pr_debug(format, a...) DCCP_PR_DEBUG(tfrc_debug, format, ##a)
22c40616c5SGerrit Renker #else
23c40616c5SGerrit Renker #define tfrc_pr_debug(format, a...)
24c40616c5SGerrit Renker #endif
25d63d8364SGerrit Renker
26d63d8364SGerrit Renker /* integer-arithmetic divisions of type (a * 1000000)/b */
scaled_div(u64 a,u64 b)277deb0f85SGerrit Renker static inline u64 scaled_div(u64 a, u64 b)
28d63d8364SGerrit Renker {
29d63d8364SGerrit Renker BUG_ON(b == 0);
307deb0f85SGerrit Renker return div64_u64(a * 1000000, b);
31d63d8364SGerrit Renker }
32d63d8364SGerrit Renker
scaled_div32(u64 a,u64 b)337deb0f85SGerrit Renker static inline u32 scaled_div32(u64 a, u64 b)
34d63d8364SGerrit Renker {
35d63d8364SGerrit Renker u64 result = scaled_div(a, b);
36d63d8364SGerrit Renker
37d63d8364SGerrit Renker if (result > UINT_MAX) {
387deb0f85SGerrit Renker DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX",
397deb0f85SGerrit Renker (unsigned long long)a, (unsigned long long)b);
40d63d8364SGerrit Renker return UINT_MAX;
41d63d8364SGerrit Renker }
42d63d8364SGerrit Renker return result;
43d63d8364SGerrit Renker }
4436729c1aSArnaldo Carvalho de Melo
45c3ada46aSGerrit Renker /**
46c3ada46aSGerrit Renker * tfrc_ewma - Exponentially weighted moving average
47c3ada46aSGerrit Renker * @weight: Weight to be used as damping factor, in units of 1/10
48c3ada46aSGerrit Renker */
tfrc_ewma(const u32 avg,const u32 newval,const u8 weight)49c3ada46aSGerrit Renker static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
50c3ada46aSGerrit Renker {
51c3ada46aSGerrit Renker return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval;
52c3ada46aSGerrit Renker }
53c3ada46aSGerrit Renker
54a402a5aaSJoe Perches u32 tfrc_calc_x(u16 s, u32 R, u32 p);
55a402a5aaSJoe Perches u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
56a402a5aaSJoe Perches u32 tfrc_invert_loss_event_rate(u32 loss_event_rate);
5736729c1aSArnaldo Carvalho de Melo
58a402a5aaSJoe Perches int tfrc_tx_packet_history_init(void);
59a402a5aaSJoe Perches void tfrc_tx_packet_history_exit(void);
60a402a5aaSJoe Perches int tfrc_rx_packet_history_init(void);
61a402a5aaSJoe Perches void tfrc_rx_packet_history_exit(void);
621e2f0e5eSGerrit Renker
63a402a5aaSJoe Perches int tfrc_li_init(void);
64a402a5aaSJoe Perches void tfrc_li_exit(void);
65129fa447SGerrit Renker
66129fa447SGerrit Renker #ifdef CONFIG_IP_DCCP_TFRC_LIB
67a402a5aaSJoe Perches int tfrc_lib_init(void);
68a402a5aaSJoe Perches void tfrc_lib_exit(void);
69129fa447SGerrit Renker #else
70129fa447SGerrit Renker #define tfrc_lib_init() (0)
71129fa447SGerrit Renker #define tfrc_lib_exit()
72129fa447SGerrit Renker #endif
7336729c1aSArnaldo Carvalho de Melo #endif /* _TFRC_H_ */
74