18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci#ifndef _TFRC_H_ 38c2ecf20Sopenharmony_ci#define _TFRC_H_ 48c2ecf20Sopenharmony_ci/* 58c2ecf20Sopenharmony_ci * Copyright (c) 2007 The University of Aberdeen, Scotland, UK 68c2ecf20Sopenharmony_ci * Copyright (c) 2005-6 The University of Waikato, Hamilton, New Zealand. 78c2ecf20Sopenharmony_ci * Copyright (c) 2005-6 Ian McDonald <ian.mcdonald@jandi.co.nz> 88c2ecf20Sopenharmony_ci * Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 98c2ecf20Sopenharmony_ci * Copyright (c) 2003 Nils-Erik Mattsson, Joacim Haggmark, Magnus Erixzon 108c2ecf20Sopenharmony_ci */ 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci#include <linux/math64.h> 138c2ecf20Sopenharmony_ci#include "../../dccp.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* internal includes that this library exports: */ 168c2ecf20Sopenharmony_ci#include "loss_interval.h" 178c2ecf20Sopenharmony_ci#include "packet_history.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#ifdef CONFIG_IP_DCCP_TFRC_DEBUG 208c2ecf20Sopenharmony_ciextern bool tfrc_debug; 218c2ecf20Sopenharmony_ci#define tfrc_pr_debug(format, a...) DCCP_PR_DEBUG(tfrc_debug, format, ##a) 228c2ecf20Sopenharmony_ci#else 238c2ecf20Sopenharmony_ci#define tfrc_pr_debug(format, a...) 248c2ecf20Sopenharmony_ci#endif 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* integer-arithmetic divisions of type (a * 1000000)/b */ 278c2ecf20Sopenharmony_cistatic inline u64 scaled_div(u64 a, u64 b) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci BUG_ON(b == 0); 308c2ecf20Sopenharmony_ci return div64_u64(a * 1000000, b); 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic inline u32 scaled_div32(u64 a, u64 b) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci u64 result = scaled_div(a, b); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (result > UINT_MAX) { 388c2ecf20Sopenharmony_ci DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX", 398c2ecf20Sopenharmony_ci (unsigned long long)a, (unsigned long long)b); 408c2ecf20Sopenharmony_ci return UINT_MAX; 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci return result; 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci/** 468c2ecf20Sopenharmony_ci * tfrc_ewma - Exponentially weighted moving average 478c2ecf20Sopenharmony_ci * @weight: Weight to be used as damping factor, in units of 1/10 488c2ecf20Sopenharmony_ci */ 498c2ecf20Sopenharmony_cistatic inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciu32 tfrc_calc_x(u16 s, u32 R, u32 p); 558c2ecf20Sopenharmony_ciu32 tfrc_calc_x_reverse_lookup(u32 fvalue); 568c2ecf20Sopenharmony_ciu32 tfrc_invert_loss_event_rate(u32 loss_event_rate); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ciint tfrc_tx_packet_history_init(void); 598c2ecf20Sopenharmony_civoid tfrc_tx_packet_history_exit(void); 608c2ecf20Sopenharmony_ciint tfrc_rx_packet_history_init(void); 618c2ecf20Sopenharmony_civoid tfrc_rx_packet_history_exit(void); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciint tfrc_li_init(void); 648c2ecf20Sopenharmony_civoid tfrc_li_exit(void); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#ifdef CONFIG_IP_DCCP_TFRC_LIB 678c2ecf20Sopenharmony_ciint tfrc_lib_init(void); 688c2ecf20Sopenharmony_civoid tfrc_lib_exit(void); 698c2ecf20Sopenharmony_ci#else 708c2ecf20Sopenharmony_ci#define tfrc_lib_init() (0) 718c2ecf20Sopenharmony_ci#define tfrc_lib_exit() 728c2ecf20Sopenharmony_ci#endif 738c2ecf20Sopenharmony_ci#endif /* _TFRC_H_ */ 74