Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/atm/atm_misc.c
15109 views
1
/* net/atm/atm_misc.c - Various functions for use by ATM drivers */
2
3
/* Written 1995-2000 by Werner Almesberger, EPFL ICA */
4
5
#include <linux/module.h>
6
#include <linux/atm.h>
7
#include <linux/atmdev.h>
8
#include <linux/skbuff.h>
9
#include <linux/sonet.h>
10
#include <linux/bitops.h>
11
#include <linux/errno.h>
12
#include <asm/atomic.h>
13
14
int atm_charge(struct atm_vcc *vcc, int truesize)
15
{
16
atm_force_charge(vcc, truesize);
17
if (atomic_read(&sk_atm(vcc)->sk_rmem_alloc) <= sk_atm(vcc)->sk_rcvbuf)
18
return 1;
19
atm_return(vcc, truesize);
20
atomic_inc(&vcc->stats->rx_drop);
21
return 0;
22
}
23
EXPORT_SYMBOL(atm_charge);
24
25
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc, int pdu_size,
26
gfp_t gfp_flags)
27
{
28
struct sock *sk = sk_atm(vcc);
29
int guess = atm_guess_pdu2truesize(pdu_size);
30
31
atm_force_charge(vcc, guess);
32
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) {
33
struct sk_buff *skb = alloc_skb(pdu_size, gfp_flags);
34
35
if (skb) {
36
atomic_add(skb->truesize-guess,
37
&sk->sk_rmem_alloc);
38
return skb;
39
}
40
}
41
atm_return(vcc, guess);
42
atomic_inc(&vcc->stats->rx_drop);
43
return NULL;
44
}
45
EXPORT_SYMBOL(atm_alloc_charge);
46
47
48
/*
49
* atm_pcr_goal returns the positive PCR if it should be rounded up, the
50
* negative PCR if it should be rounded down, and zero if the maximum available
51
* bandwidth should be used.
52
*
53
* The rules are as follows (* = maximum, - = absent (0), x = value "x",
54
* (x+ = x or next value above x, x- = x or next value below):
55
*
56
* min max pcr result min max pcr result
57
* - - - * (UBR only) x - - x+
58
* - - * * x - * *
59
* - - z z- x - z z-
60
* - * - * x * - x+
61
* - * * * x * * *
62
* - * z z- x * z z-
63
* - y - y- x y - x+
64
* - y * y- x y * y-
65
* - y z z- x y z z-
66
*
67
* All non-error cases can be converted with the following simple set of rules:
68
*
69
* if pcr == z then z-
70
* else if min == x && pcr == - then x+
71
* else if max == y then y-
72
* else *
73
*/
74
75
int atm_pcr_goal(const struct atm_trafprm *tp)
76
{
77
if (tp->pcr && tp->pcr != ATM_MAX_PCR)
78
return -tp->pcr;
79
if (tp->min_pcr && !tp->pcr)
80
return tp->min_pcr;
81
if (tp->max_pcr != ATM_MAX_PCR)
82
return -tp->max_pcr;
83
return 0;
84
}
85
EXPORT_SYMBOL(atm_pcr_goal);
86
87
void sonet_copy_stats(struct k_sonet_stats *from, struct sonet_stats *to)
88
{
89
#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
90
__SONET_ITEMS
91
#undef __HANDLE_ITEM
92
}
93
EXPORT_SYMBOL(sonet_copy_stats);
94
95
void sonet_subtract_stats(struct k_sonet_stats *from, struct sonet_stats *to)
96
{
97
#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
98
__SONET_ITEMS
99
#undef __HANDLE_ITEM
100
}
101
EXPORT_SYMBOL(sonet_subtract_stats);
102
103