162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci#ifndef _DCCP_LI_HIST_
362306a36Sopenharmony_ci#define _DCCP_LI_HIST_
462306a36Sopenharmony_ci/*
562306a36Sopenharmony_ci *  Copyright (c) 2007   The University of Aberdeen, Scotland, UK
662306a36Sopenharmony_ci *  Copyright (c) 2005-7 The University of Waikato, Hamilton, New Zealand.
762306a36Sopenharmony_ci *  Copyright (c) 2005-7 Ian McDonald <ian.mcdonald@jandi.co.nz>
862306a36Sopenharmony_ci *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#include <linux/ktime.h>
1162306a36Sopenharmony_ci#include <linux/list.h>
1262306a36Sopenharmony_ci#include <linux/slab.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * Number of loss intervals (RFC 4342, 8.6.1). The history size is one more than
1662306a36Sopenharmony_ci * NINTERVAL, since the `open' interval I_0 is always stored as the first entry.
1762306a36Sopenharmony_ci */
1862306a36Sopenharmony_ci#define NINTERVAL	8
1962306a36Sopenharmony_ci#define LIH_SIZE	(NINTERVAL + 1)
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/**
2262306a36Sopenharmony_ci *  tfrc_loss_interval  -  Loss history record for TFRC-based protocols
2362306a36Sopenharmony_ci *  @li_seqno:		Highest received seqno before the start of loss
2462306a36Sopenharmony_ci *  @li_ccval:		The CCVal belonging to @li_seqno
2562306a36Sopenharmony_ci *  @li_is_closed:	Whether @li_seqno is older than 1 RTT
2662306a36Sopenharmony_ci *  @li_length:		Loss interval sequence length
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_cistruct tfrc_loss_interval {
2962306a36Sopenharmony_ci	u64		 li_seqno:48,
3062306a36Sopenharmony_ci			 li_ccval:4,
3162306a36Sopenharmony_ci			 li_is_closed:1;
3262306a36Sopenharmony_ci	u32		 li_length;
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/**
3662306a36Sopenharmony_ci *  tfrc_loss_hist  -  Loss record database
3762306a36Sopenharmony_ci *  @ring:	Circular queue managed in LIFO manner
3862306a36Sopenharmony_ci *  @counter:	Current count of entries (can be more than %LIH_SIZE)
3962306a36Sopenharmony_ci *  @i_mean:	Current Average Loss Interval [RFC 3448, 5.4]
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_cistruct tfrc_loss_hist {
4262306a36Sopenharmony_ci	struct tfrc_loss_interval	*ring[LIH_SIZE];
4362306a36Sopenharmony_ci	u8				counter;
4462306a36Sopenharmony_ci	u32				i_mean;
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic inline void tfrc_lh_init(struct tfrc_loss_hist *lh)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	memset(lh, 0, sizeof(struct tfrc_loss_hist));
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic inline u8 tfrc_lh_is_initialised(struct tfrc_loss_hist *lh)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	return lh->counter > 0;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cistatic inline u8 tfrc_lh_length(struct tfrc_loss_hist *lh)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	return min(lh->counter, (u8)LIH_SIZE);
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistruct tfrc_rx_hist;
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciint tfrc_lh_interval_add(struct tfrc_loss_hist *, struct tfrc_rx_hist *,
6562306a36Sopenharmony_ci			 u32 (*first_li)(struct sock *), struct sock *);
6662306a36Sopenharmony_ciu8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *);
6762306a36Sopenharmony_civoid tfrc_lh_cleanup(struct tfrc_loss_hist *lh);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci#endif /* _DCCP_LI_HIST_ */
70