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