fix qdisc ordering
[openwrt.git] / target / linux / linux-2.4 / patches / 002-wl_fix.patch
1 diff -Nur linux-2.4.30/include/linux/netdevice.h linux-2.4.30-wl-fix/include/linux/netdevice.h
2 --- linux-2.4.30/include/linux/netdevice.h 2004-11-17 12:54:22.000000000 +0100
3 +++ linux-2.4.30-wl-fix/include/linux/netdevice.h 2005-05-09 16:31:08.000000000 +0200
4 @@ -297,7 +297,7 @@
5 * See <net/iw_handler.h> for details. Jean II */
6 struct iw_handler_def * wireless_handlers;
7
8 - struct ethtool_ops *ethtool_ops;
9 +
10
11 /*
12 * This marks the end of the "visible" part of the structure. All
13 @@ -352,8 +355,8 @@
14
15 struct Qdisc *qdisc;
16 struct Qdisc *qdisc_sleeping;
17 + struct Qdisc *qdisc_list;
18 struct Qdisc *qdisc_ingress;
19 - struct list_head qdisc_list;
20 unsigned long tx_queue_len; /* Max frames per queue allowed */
21
22 /* hard_start_xmit synchronizer */
23 struct Qdisc *qdisc;
24 struct Qdisc *qdisc_sleeping;
25 struct Qdisc *qdisc_ingress;
26 + /*
27 + * this is needed for the wlan driver binary blob from linksys
28 + */
29 +#ifdef CONFIG_BCM4710
30 + struct Qdisc *qdisc_list;
31 +#else
32 struct list_head qdisc_list;
33 +#endif
34 unsigned long tx_queue_len; /* Max frames per queue allowed */
35
36 /* hard_start_xmit synchronizer */
37 @@ -453,6 +460,7 @@
38 /* this will get initialized at each interface type init routine */
39 struct divert_blk *divert;
40 #endif /* CONFIG_NET_DIVERT */
41 + struct ethtool_ops *ethtool_ops;
42 };
43
44 /* 2.6 compatibility */
45 diff -Nur linux-2.4.30/include/linux/skbuff.h linux-2.4.30-wl-fix/include/linux/skbuff.h
46 --- linux-2.4.30/include/linux/skbuff.h 2005-04-04 03:42:20.000000000 +0200
47 +++ linux-2.4.30-wl-fix/include/linux/skbuff.h 2005-05-08 00:50:55.000000000 +0200
48 @@ -135,10 +135,6 @@
49 struct sock *sk; /* Socket we are owned by */
50 struct timeval stamp; /* Time we arrived */
51 struct net_device *dev; /* Device we arrived on/are leaving by */
52 - struct net_device *real_dev; /* For support of point to point protocols
53 - (e.g. 802.3ad) over bonding, we must save the
54 - physical device that got the packet before
55 - replacing skb->dev with the virtual device. */
56
57 /* Transport layer header */
58 union
59 @@ -219,6 +215,10 @@
60 #ifdef CONFIG_NET_SCHED
61 __u32 tc_index; /* traffic control index */
62 #endif
63 + struct net_device *real_dev; /* For support of point to point protocols
64 + (e.g. 802.3ad) over bonding, we must save the
65 + physical device that got the packet before
66 + replacing skb->dev with the virtual device. */
67 };
68
69 #ifdef __KERNEL__
70 diff -Nur linux-2.4.30/include/net/pkt_sched.h linux-2.4.30-wl-fix/include/net/pkt_sched.h
71 --- linux-2.4.30/include/net/pkt_sched.h 2004-11-17 12:54:22.000000000 +0100
72 +++ linux-2.4.30-wl-fix/include/net/pkt_sched.h 2005-05-08 01:05:48.000000000 +0200
73 @@ -59,8 +59,11 @@
74 int (*enqueue)(struct sk_buff *, struct Qdisc *);
75 struct sk_buff * (*dequeue)(struct Qdisc *);
76 int (*requeue)(struct sk_buff *, struct Qdisc *);
77 - unsigned int (*drop)(struct Qdisc *);
78 -
79 +#ifdef CONFIG_BCM4710
80 + int (*drop)(struct Qdisc *);
81 +#else
82 + unsigned int (*drop)(struct Qdisc *);
83 +#endif
84 int (*init)(struct Qdisc *, struct rtattr *arg);
85 void (*reset)(struct Qdisc *);
86 void (*destroy)(struct Qdisc *);
87 @@ -80,12 +83,19 @@
88 #define TCQ_F_THROTTLED 2
89 #define TCQ_F_INGRESS 4
90 struct Qdisc_ops *ops;
91 +#ifdef CONFIG_BCM4710
92 + struct Qdisc *next;
93 +#endif
94 u32 handle;
95 - u32 parent;
96 +#ifndef CONFIG_BCM4710
97 + u32 parent;
98 +#endif
99 atomic_t refcnt;
100 struct sk_buff_head q;
101 struct net_device *dev;
102 - struct list_head list;
103 +#ifndef CONFIG_BCM4710
104 + struct list_head list;
105 +#endif
106
107 struct tc_stats stats;
108 int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);
109 diff -Nur linux-2.4.30/net/core/dev.c linux-2.4.30-wl-fix/net/core/dev.c
110 --- linux-2.4.30/net/core/dev.c 2005-04-04 03:42:20.000000000 +0200
111 +++ linux-2.4.30-wl-fix/net/core/dev.c 2005-05-08 00:51:08.000000000 +0200
112 @@ -2311,6 +2311,7 @@
113 }
114 return ret;
115
116 +#ifndef CONFIG_BCM4710
117 case SIOCETHTOOL:
118 dev_load(ifr.ifr_name);
119 rtnl_lock();
120 @@ -2324,6 +2325,7 @@
121 ret = -EFAULT;
122 }
123 return ret;
124 +#endif
125
126 /*
127 * These ioctl calls:
128 diff -Nur linux-2.4.30/net/core/Makefile linux-2.4.30-wl-fix/net/core/Makefile
129 --- linux-2.4.30/net/core/Makefile 2004-11-17 12:54:22.000000000 +0100
130 +++ linux-2.4.30-wl-fix/net/core/Makefile 2005-05-08 00:51:02.000000000 +0200
131 @@ -9,7 +9,11 @@
132
133 O_TARGET := core.o
134
135 +ifeq ($(CONFIG_BCM4710),y)
136 +export-objs := netfilter.o profile.o neighbour.o
137 +else
138 export-objs := netfilter.o profile.o ethtool.o neighbour.o
139 +endif
140
141 obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
142
143 @@ -21,8 +25,13 @@
144
145 obj-$(CONFIG_FILTER) += filter.o
146
147 +ifeq ($(CONFIG_BCM4710),y)
148 +obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o \
149 + rtnetlink.o utils.o
150 +else
151 obj-$(CONFIG_NET) += dev.o ethtool.o dev_mcast.o dst.o neighbour.o \
152 rtnetlink.o utils.o
153 +endif
154
155 obj-$(CONFIG_NETFILTER) += netfilter.o
156 obj-$(CONFIG_NET_DIVERT) += dv.o
157 diff -Nur linux-2.4.30/net/sched/sch_api.c linux-2.4.30-wl-fix/net/sched/sch_api.c
158 --- linux-2.4.30/net/sched/sch_api.c 2004-11-17 12:54:22.000000000 +0100
159 +++ linux-2.4.30-wl-fix/net/sched/sch_api.c 2005-05-08 00:51:14.000000000 +0200
160 @@ -194,11 +194,12 @@
161 {
162 struct Qdisc *q;
163
164 - list_for_each_entry(q, &dev->qdisc_list, list) {
165 + for (q = dev->qdisc_list; q; q = q->next) {
166 if (q->handle == handle)
167 return q;
168 }
169 return NULL;
170 +
171 }
172
173 struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
174 @@ -371,8 +372,6 @@
175 unsigned long cl = cops->get(parent, classid);
176 if (cl) {
177 err = cops->graft(parent, cl, new, old);
178 - if (new)
179 - new->parent = classid;
180 cops->put(parent, cl);
181 }
182 }
183 @@ -427,7 +426,6 @@
184
185 memset(sch, 0, size);
186
187 - INIT_LIST_HEAD(&sch->list);
188 skb_queue_head_init(&sch->q);
189
190 if (handle == TC_H_INGRESS)
191 @@ -453,7 +451,8 @@
192
193 if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
194 write_lock(&qdisc_tree_lock);
195 - list_add_tail(&sch->list, &dev->qdisc_list);
196 + sch->next = dev->qdisc_list;
197 + dev->qdisc_list = sch;
198 write_unlock(&qdisc_tree_lock);
199 #ifdef CONFIG_NET_ESTIMATOR
200 if (tca[TCA_RATE-1])
201 @@ -808,19 +807,16 @@
202 if (idx > s_idx)
203 s_q_idx = 0;
204 read_lock(&qdisc_tree_lock);
205 - q_idx = 0;
206 - list_for_each_entry(q, &dev->qdisc_list, list) {
207 - if (q_idx < s_q_idx) {
208 - q_idx++;
209 - continue;
210 - }
211 - if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
212 - cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
213 - read_unlock(&qdisc_tree_lock);
214 - goto done;
215 - }
216 - q_idx++;
217 - }
218 + for (q = dev->qdisc_list, q_idx = 0; q;
219 + q = q->next, q_idx++) {
220 + if (q_idx < s_q_idx)
221 + continue;
222 + if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid,
223 + cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
224 + read_unlock(&qdisc_tree_lock);
225 + goto done;
226 + }
227 + }
228 read_unlock(&qdisc_tree_lock);
229 }
230
231 @@ -1033,27 +1029,24 @@
232 t = 0;
233
234 read_lock(&qdisc_tree_lock);
235 - list_for_each_entry(q, &dev->qdisc_list, list) {
236 - if (t < s_t || !q->ops->cl_ops ||
237 - (tcm->tcm_parent &&
238 - TC_H_MAJ(tcm->tcm_parent) != q->handle)) {
239 - t++;
240 - continue;
241 - }
242 - if (t > s_t)
243 - memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
244 - arg.w.fn = qdisc_class_dump;
245 - arg.skb = skb;
246 - arg.cb = cb;
247 - arg.w.stop = 0;
248 - arg.w.skip = cb->args[1];
249 - arg.w.count = 0;
250 - q->ops->cl_ops->walk(q, &arg.w);
251 - cb->args[1] = arg.w.count;
252 - if (arg.w.stop)
253 - break;
254 - t++;
255 - }
256 + for (q=dev->qdisc_list, t=0; q; q = q->next, t++) {
257 + if (t < s_t) continue;
258 + if (!q->ops->cl_ops) continue;
259 + if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle)
260 + continue;
261 + if (t > s_t)
262 + memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
263 + arg.w.fn = qdisc_class_dump;
264 + arg.skb = skb;
265 + arg.cb = cb;
266 + arg.w.stop = 0;
267 + arg.w.skip = cb->args[1];
268 + arg.w.count = 0;
269 + q->ops->cl_ops->walk(q, &arg.w);
270 + cb->args[1] = arg.w.count;
271 + if (arg.w.stop)
272 + break;
273 + }
274 read_unlock(&qdisc_tree_lock);
275
276 cb->args[0] = t;
277 diff -Nur linux-2.4.30/net/sched/sch_generic.c linux-2.4.30-wl-fix/net/sched/sch_generic.c
278 --- linux-2.4.30/net/sched/sch_generic.c 2004-11-17 12:54:22.000000000 +0100
279 +++ linux-2.4.30-wl-fix/net/sched/sch_generic.c 2005-05-08 00:51:20.000000000 +0200
280 @@ -392,7 +392,6 @@
281 return NULL;
282 memset(sch, 0, size);
283
284 - INIT_LIST_HEAD(&sch->list);
285 skb_queue_head_init(&sch->q);
286 sch->ops = ops;
287 sch->enqueue = ops->enqueue;
288 @@ -422,11 +421,22 @@
289 void qdisc_destroy(struct Qdisc *qdisc)
290 {
291 struct Qdisc_ops *ops = qdisc->ops;
292 + struct net_device *dev;
293
294 if (qdisc->flags&TCQ_F_BUILTIN ||
295 !atomic_dec_and_test(&qdisc->refcnt))
296 return;
297 - list_del(&qdisc->list);
298 +
299 + dev = qdisc->dev;
300 + if (dev) {
301 + struct Qdisc *q, **qp;
302 + for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) {
303 + if (q == qdisc) {
304 + *qp = q->next;
305 + break;
306 + }
307 + }
308 + }
309 #ifdef CONFIG_NET_ESTIMATOR
310 qdisc_kill_estimator(&qdisc->stats);
311 #endif
312 @@ -455,9 +465,9 @@
313 return;
314 }
315 write_lock(&qdisc_tree_lock);
316 - list_add_tail(&qdisc->list, &dev->qdisc_list);
317 + qdisc->next = dev->qdisc_list;
318 + dev->qdisc_list = qdisc;
319 write_unlock(&qdisc_tree_lock);
320 -
321 } else {
322 qdisc = &noqueue_qdisc;
323 }
324 @@ -501,7 +511,7 @@
325 dev->qdisc = &noop_qdisc;
326 spin_unlock_bh(&dev->queue_lock);
327 dev->qdisc_sleeping = &noop_qdisc;
328 - INIT_LIST_HEAD(&dev->qdisc_list);
329 + dev->qdisc_list = NULL;
330 write_unlock(&qdisc_tree_lock);
331
332 dev_watchdog_init(dev);
333 @@ -523,7 +533,7 @@
334 qdisc_destroy(qdisc);
335 }
336 #endif
337 - BUG_TRAP(list_empty(&dev->qdisc_list));
338 + BUG_TRAP(dev->qdisc_list == NULL);
339 BUG_TRAP(!timer_pending(&dev->watchdog_timer));
340 spin_unlock_bh(&dev->queue_lock);
341 write_unlock(&qdisc_tree_lock);
342 diff -urN linux.old/net/core/dev.c linux.dev/net/core/dev.c
343 --- linux.old/net/core/dev.c 2005-05-28 17:42:07.000000000 +0200
344 +++ linux.dev/net/core/dev.c 2005-05-28 20:38:06.000000000 +0200
345 @@ -2223,6 +2223,7 @@
346 cmd == SIOCGMIIPHY ||
347 cmd == SIOCGMIIREG ||
348 cmd == SIOCSMIIREG ||
349 + cmd == SIOCETHTOOL ||
350 cmd == SIOCWANDEV) {
351 if (dev->do_ioctl) {
352 if (!netif_device_present(dev))
353 @@ -2405,6 +2406,7 @@
354
355 default:
356 if (cmd == SIOCWANDEV ||
357 + (cmd == SIOCETHTOOL) ||
358 (cmd >= SIOCDEVPRIVATE &&
359 cmd <= SIOCDEVPRIVATE + 15)) {
360 dev_load(ifr.ifr_name);
This page took 0.065124 seconds and 5 git commands to generate.