OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [sched/] [sch_fifo.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * net/sched/sch_fifo.c The simplest FIFO queue.
3
 *
4
 *              This program is free software; you can redistribute it and/or
5
 *              modify it under the terms of the GNU General Public License
6
 *              as published by the Free Software Foundation; either version
7
 *              2 of the License, or (at your option) any later version.
8
 *
9
 * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10
 */
11
 
12
#include <linux/config.h>
13
#include <asm/uaccess.h>
14
#include <asm/system.h>
15
#include <asm/bitops.h>
16
#include <linux/types.h>
17
#include <linux/kernel.h>
18
#include <linux/sched.h>
19
#include <linux/string.h>
20
#include <linux/mm.h>
21
#include <linux/socket.h>
22
#include <linux/sockios.h>
23
#include <linux/in.h>
24
#include <linux/errno.h>
25
#include <linux/interrupt.h>
26
#include <linux/if_ether.h>
27
#include <linux/inet.h>
28
#include <linux/netdevice.h>
29
#include <linux/etherdevice.h>
30
#include <linux/notifier.h>
31
#include <net/ip.h>
32
#include <net/route.h>
33
#include <linux/skbuff.h>
34
#include <net/sock.h>
35
#include <net/pkt_sched.h>
36
 
37
/* 1 band FIFO pseudo-"scheduler" */
38
 
39
struct fifo_sched_data
40
{
41
        unsigned limit;
42
};
43
 
44
static int
45
bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
46
{
47
        struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data;
48
 
49
        if (sch->stats.backlog + skb->len <= q->limit) {
50
                __skb_queue_tail(&sch->q, skb);
51
                sch->stats.backlog += skb->len;
52
                sch->stats.bytes += skb->len;
53
                sch->stats.packets++;
54
                return 0;
55
        }
56
        sch->stats.drops++;
57
#ifdef CONFIG_NET_CLS_POLICE
58
        if (sch->reshape_fail==NULL || sch->reshape_fail(skb, sch))
59
#endif
60
                kfree_skb(skb);
61
        return NET_XMIT_DROP;
62
}
63
 
64
static int
65
bfifo_requeue(struct sk_buff *skb, struct Qdisc* sch)
66
{
67
        __skb_queue_head(&sch->q, skb);
68
        sch->stats.backlog += skb->len;
69
        return 0;
70
}
71
 
72
static struct sk_buff *
73
bfifo_dequeue(struct Qdisc* sch)
74
{
75
        struct sk_buff *skb;
76
 
77
        skb = __skb_dequeue(&sch->q);
78
        if (skb)
79
                sch->stats.backlog -= skb->len;
80
        return skb;
81
}
82
 
83
static unsigned int
84
fifo_drop(struct Qdisc* sch)
85
{
86
        struct sk_buff *skb;
87
 
88
        skb = __skb_dequeue_tail(&sch->q);
89
        if (skb) {
90
                unsigned int len = skb->len;
91
                sch->stats.backlog -= len;
92
                kfree_skb(skb);
93
                return len;
94
        }
95
        return 0;
96
}
97
 
98
static void
99
fifo_reset(struct Qdisc* sch)
100
{
101
        skb_queue_purge(&sch->q);
102
        sch->stats.backlog = 0;
103
}
104
 
105
static int
106
pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
107
{
108
        struct fifo_sched_data *q = (struct fifo_sched_data *)sch->data;
109
 
110
        if (sch->q.qlen < q->limit) {
111
                __skb_queue_tail(&sch->q, skb);
112
                sch->stats.bytes += skb->len;
113
                sch->stats.packets++;
114
                return 0;
115
        }
116
        sch->stats.drops++;
117
#ifdef CONFIG_NET_CLS_POLICE
118
        if (sch->reshape_fail==NULL || sch->reshape_fail(skb, sch))
119
#endif
120
                kfree_skb(skb);
121
        return NET_XMIT_DROP;
122
}
123
 
124
static int
125
pfifo_requeue(struct sk_buff *skb, struct Qdisc* sch)
126
{
127
        __skb_queue_head(&sch->q, skb);
128
        return 0;
129
}
130
 
131
 
132
static struct sk_buff *
133
pfifo_dequeue(struct Qdisc* sch)
134
{
135
        return __skb_dequeue(&sch->q);
136
}
137
 
138
static int fifo_init(struct Qdisc *sch, struct rtattr *opt)
139
{
140
        struct fifo_sched_data *q = (void*)sch->data;
141
 
142
        if (opt == NULL) {
143
                unsigned int limit = sch->dev->tx_queue_len ? : 1;
144
 
145
                if (sch->ops == &bfifo_qdisc_ops)
146
                        q->limit = limit*sch->dev->mtu;
147
                else
148
                        q->limit = limit;
149
        } else {
150
                struct tc_fifo_qopt *ctl = RTA_DATA(opt);
151
                if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
152
                        return -EINVAL;
153
                q->limit = ctl->limit;
154
        }
155
        return 0;
156
}
157
 
158
static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
159
{
160
        struct fifo_sched_data *q = (void*)sch->data;
161
        unsigned char    *b = skb->tail;
162
        struct tc_fifo_qopt opt;
163
 
164
        opt.limit = q->limit;
165
        RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
166
 
167
        return skb->len;
168
 
169
rtattr_failure:
170
        skb_trim(skb, b - skb->data);
171
        return -1;
172
}
173
 
174
struct Qdisc_ops pfifo_qdisc_ops =
175
{
176
        NULL,
177
        NULL,
178
        "pfifo",
179
        sizeof(struct fifo_sched_data),
180
 
181
        pfifo_enqueue,
182
        pfifo_dequeue,
183
        pfifo_requeue,
184
        fifo_drop,
185
 
186
        fifo_init,
187
        fifo_reset,
188
        NULL,
189
        fifo_init,
190
 
191
        fifo_dump,
192
};
193
 
194
struct Qdisc_ops bfifo_qdisc_ops =
195
{
196
        NULL,
197
        NULL,
198
        "bfifo",
199
        sizeof(struct fifo_sched_data),
200
 
201
        bfifo_enqueue,
202
        bfifo_dequeue,
203
        bfifo_requeue,
204
        fifo_drop,
205
 
206
        fifo_init,
207
        fifo_reset,
208
        NULL,
209
        fifo_init,
210
        fifo_dump,
211
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.