summaryrefslogtreecommitdiff
path: root/target/linux/brcm-2.4/patches/002-wl_fix.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm-2.4/patches/002-wl_fix.patch')
-rw-r--r--target/linux/brcm-2.4/patches/002-wl_fix.patch348
1 files changed, 348 insertions, 0 deletions
diff --git a/target/linux/brcm-2.4/patches/002-wl_fix.patch b/target/linux/brcm-2.4/patches/002-wl_fix.patch
new file mode 100644
index 0000000..95044b6
--- /dev/null
+++ b/target/linux/brcm-2.4/patches/002-wl_fix.patch
@@ -0,0 +1,348 @@
+diff -urN linux.old/include/linux/netdevice.h linux.dev/include/linux/netdevice.h
+--- linux.old/include/linux/netdevice.h 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/include/linux/netdevice.h 2006-03-19 06:33:21.000000000 +0100
+@@ -296,10 +296,7 @@
+ /* List of functions to handle Wireless Extensions (instead of ioctl).
+ * See <net/iw_handler.h> for details. Jean II */
+ const struct iw_handler_def * wireless_handlers;
+- /* Instance data managed by the core of Wireless Extensions. */
+- struct iw_public_data * wireless_data;
+
+- struct ethtool_ops *ethtool_ops;
+
+ /*
+ * This marks the end of the "visible" part of the structure. All
+@@ -354,8 +351,8 @@
+
+ struct Qdisc *qdisc;
+ struct Qdisc *qdisc_sleeping;
++ struct Qdisc *qdisc_list;
+ struct Qdisc *qdisc_ingress;
+- struct list_head qdisc_list;
+ unsigned long tx_queue_len; /* Max frames per queue allowed */
+
+ /* hard_start_xmit synchronizer */
+@@ -455,6 +452,10 @@
+ /* this will get initialized at each interface type init routine */
+ struct divert_blk *divert;
+ #endif /* CONFIG_NET_DIVERT */
++ struct ethtool_ops *ethtool_ops;
++
++ /* Instance data managed by the core of Wireless Extensions. */
++ struct iw_public_data * wireless_data;
+ };
+
+ /* 2.6 compatibility */
+diff -urN linux.old/include/linux/skbuff.h linux.dev/include/linux/skbuff.h
+--- linux.old/include/linux/skbuff.h 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/include/linux/skbuff.h 2006-03-19 06:29:41.000000000 +0100
+@@ -138,10 +138,6 @@
+ struct sock *sk; /* Socket we are owned by */
+ struct timeval stamp; /* Time we arrived */
+ struct net_device *dev; /* Device we arrived on/are leaving by */
+- struct net_device *real_dev; /* For support of point to point protocols
+- (e.g. 802.3ad) over bonding, we must save the
+- physical device that got the packet before
+- replacing skb->dev with the virtual device. */
+
+ /* Transport layer header */
+ union
+@@ -225,6 +221,10 @@
+ #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE)
+ struct nf_info *nf_info;
+ #endif
++ struct net_device *real_dev; /* For support of point to point protocols
++ (e.g. 802.3ad) over bonding, we must save the
++ physical device that got the packet before
++ replacing skb->dev with the virtual device. */
+ };
+
+ #ifdef __KERNEL__
+diff -urN linux.old/include/net/pkt_sched.h linux.dev/include/net/pkt_sched.h
+--- linux.old/include/net/pkt_sched.h 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/include/net/pkt_sched.h 2006-03-19 06:29:41.000000000 +0100
+@@ -63,8 +63,11 @@
+ int (*enqueue)(struct sk_buff *, struct Qdisc *);
+ struct sk_buff * (*dequeue)(struct Qdisc *);
+ int (*requeue)(struct sk_buff *, struct Qdisc *);
+- unsigned int (*drop)(struct Qdisc *);
+-
++#ifdef CONFIG_BCM4710
++ int (*drop)(struct Qdisc *);
++#else
++ unsigned int (*drop)(struct Qdisc *);
++#endif
+ int (*init)(struct Qdisc *, struct rtattr *arg);
+ void (*reset)(struct Qdisc *);
+ void (*destroy)(struct Qdisc *);
+@@ -84,12 +87,19 @@
+ #define TCQ_F_THROTTLED 2
+ #define TCQ_F_INGRESS 4
+ struct Qdisc_ops *ops;
++#ifdef CONFIG_BCM4710
++ struct Qdisc *next;
++#endif
+ u32 handle;
+- u32 parent;
++#ifndef CONFIG_BCM4710
++ u32 parent;
++#endif
+ atomic_t refcnt;
+ struct sk_buff_head q;
+ struct net_device *dev;
+- struct list_head list;
++#ifndef CONFIG_BCM4710
++ struct list_head list;
++#endif
+
+ struct tc_stats stats;
+ int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);
+diff -urN linux.old/net/core/Makefile linux.dev/net/core/Makefile
+--- linux.old/net/core/Makefile 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/net/core/Makefile 2006-03-19 06:29:41.000000000 +0100
+@@ -9,7 +9,11 @@
+
+ O_TARGET := core.o
+
++ifeq ($(CONFIG_BCM4710),y)
++export-objs := netfilter.o profile.o neighbour.o
++else
+ export-objs := netfilter.o profile.o ethtool.o neighbour.o
++endif
+
+ obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
+
+@@ -21,8 +25,13 @@
+
+ obj-$(CONFIG_FILTER) += filter.o
+
++ifeq ($(CONFIG_BCM4710),y)
++obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o \
++ rtnetlink.o utils.o
++else
+ obj-$(CONFIG_NET) += dev.o ethtool.o dev_mcast.o dst.o neighbour.o \
+ rtnetlink.o utils.o
++endif
+
+ obj-$(CONFIG_NETFILTER) += netfilter.o
+ obj-$(CONFIG_NET_DIVERT) += dv.o
+diff -urN linux.old/net/core/dev.c linux.dev/net/core/dev.c
+--- linux.old/net/core/dev.c 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/net/core/dev.c 2006-03-19 06:29:41.000000000 +0100
+@@ -2232,6 +2232,7 @@
+ cmd == SIOCGMIIPHY ||
+ cmd == SIOCGMIIREG ||
+ cmd == SIOCSMIIREG ||
++ cmd == SIOCETHTOOL ||
+ cmd == SIOCWANDEV) {
+ if (dev->do_ioctl) {
+ if (!netif_device_present(dev))
+@@ -2324,6 +2325,7 @@
+ }
+ return ret;
+
++#ifndef CONFIG_BCM4710
+ case SIOCETHTOOL:
+ dev_load(ifr.ifr_name);
+ rtnl_lock();
+@@ -2337,6 +2339,7 @@
+ ret = -EFAULT;
+ }
+ return ret;
++#endif
+
+ /*
+ * These ioctl calls:
+@@ -2412,6 +2415,7 @@
+
+ default:
+ if (cmd == SIOCWANDEV ||
++ (cmd == SIOCETHTOOL) ||
+ (cmd >= SIOCDEVPRIVATE &&
+ cmd <= SIOCDEVPRIVATE + 15)) {
+ dev_load(ifr.ifr_name);
+diff -urN linux.old/net/sched/sch_api.c linux.dev/net/sched/sch_api.c
+--- linux.old/net/sched/sch_api.c 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/net/sched/sch_api.c 2006-03-19 06:29:41.000000000 +0100
+@@ -194,11 +194,12 @@
+ {
+ struct Qdisc *q;
+
+- list_for_each_entry(q, &dev->qdisc_list, list) {
++ for (q = dev->qdisc_list; q; q = q->next) {
+ if (q->handle == handle)
+ return q;
+ }
+ return NULL;
++
+ }
+
+ struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
+@@ -371,8 +372,6 @@
+ unsigned long cl = cops->get(parent, classid);
+ if (cl) {
+ err = cops->graft(parent, cl, new, old);
+- if (new)
+- new->parent = classid;
+ cops->put(parent, cl);
+ }
+ }
+@@ -427,7 +426,6 @@
+
+ memset(sch, 0, size);
+
+- INIT_LIST_HEAD(&sch->list);
+ skb_queue_head_init(&sch->q);
+
+ if (handle == TC_H_INGRESS)
+@@ -453,7 +451,8 @@
+
+ if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) {
+ write_lock(&qdisc_tree_lock);
+- list_add_tail(&sch->list, &dev->qdisc_list);
++ sch->next = dev->qdisc_list;
++ dev->qdisc_list = sch;
+ write_unlock(&qdisc_tree_lock);
+ #ifdef CONFIG_NET_ESTIMATOR
+ if (tca[TCA_RATE-1])
+@@ -808,19 +807,16 @@
+ if (idx > s_idx)
+ s_q_idx = 0;
+ read_lock(&qdisc_tree_lock);
+- q_idx = 0;
+- list_for_each_entry(q, &dev->qdisc_list, list) {
+- if (q_idx < s_q_idx) {
+- q_idx++;
+- continue;
+- }
+- if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
+- cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
+- read_unlock(&qdisc_tree_lock);
+- goto done;
+- }
+- q_idx++;
+- }
++ for (q = dev->qdisc_list, q_idx = 0; q;
++ q = q->next, q_idx++) {
++ if (q_idx < s_q_idx)
++ continue;
++ if (tc_fill_qdisc(skb, q, 0, NETLINK_CB(cb->skb).pid,
++ cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) {
++ read_unlock(&qdisc_tree_lock);
++ goto done;
++ }
++ }
+ read_unlock(&qdisc_tree_lock);
+ }
+
+@@ -1033,27 +1029,24 @@
+ t = 0;
+
+ read_lock(&qdisc_tree_lock);
+- list_for_each_entry(q, &dev->qdisc_list, list) {
+- if (t < s_t || !q->ops->cl_ops ||
+- (tcm->tcm_parent &&
+- TC_H_MAJ(tcm->tcm_parent) != q->handle)) {
+- t++;
+- continue;
+- }
+- if (t > s_t)
+- memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
+- arg.w.fn = qdisc_class_dump;
+- arg.skb = skb;
+- arg.cb = cb;
+- arg.w.stop = 0;
+- arg.w.skip = cb->args[1];
+- arg.w.count = 0;
+- q->ops->cl_ops->walk(q, &arg.w);
+- cb->args[1] = arg.w.count;
+- if (arg.w.stop)
+- break;
+- t++;
+- }
++ for (q=dev->qdisc_list, t=0; q; q = q->next, t++) {
++ if (t < s_t) continue;
++ if (!q->ops->cl_ops) continue;
++ if (tcm->tcm_parent && TC_H_MAJ(tcm->tcm_parent) != q->handle)
++ continue;
++ if (t > s_t)
++ memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
++ arg.w.fn = qdisc_class_dump;
++ arg.skb = skb;
++ arg.cb = cb;
++ arg.w.stop = 0;
++ arg.w.skip = cb->args[1];
++ arg.w.count = 0;
++ q->ops->cl_ops->walk(q, &arg.w);
++ cb->args[1] = arg.w.count;
++ if (arg.w.stop)
++ break;
++ }
+ read_unlock(&qdisc_tree_lock);
+
+ cb->args[0] = t;
+diff -urN linux.old/net/sched/sch_generic.c linux.dev/net/sched/sch_generic.c
+--- linux.old/net/sched/sch_generic.c 2006-03-19 06:32:22.000000000 +0100
++++ linux.dev/net/sched/sch_generic.c 2006-03-19 06:29:41.000000000 +0100
+@@ -399,7 +399,6 @@
+ return NULL;
+ memset(sch, 0, size);
+
+- INIT_LIST_HEAD(&sch->list);
+ skb_queue_head_init(&sch->q);
+ sch->ops = ops;
+ sch->enqueue = ops->enqueue;
+@@ -429,11 +428,22 @@
+ void qdisc_destroy(struct Qdisc *qdisc)
+ {
+ struct Qdisc_ops *ops = qdisc->ops;
++ struct net_device *dev;
+
+ if (qdisc->flags&TCQ_F_BUILTIN ||
+ !atomic_dec_and_test(&qdisc->refcnt))
+ return;
+- list_del(&qdisc->list);
++
++ dev = qdisc->dev;
++ if (dev) {
++ struct Qdisc *q, **qp;
++ for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) {
++ if (q == qdisc) {
++ *qp = q->next;
++ break;
++ }
++ }
++ }
+ #ifdef CONFIG_NET_ESTIMATOR
+ qdisc_kill_estimator(&qdisc->stats);
+ #endif
+@@ -462,9 +472,9 @@
+ return;
+ }
+ write_lock(&qdisc_tree_lock);
+- list_add_tail(&qdisc->list, &dev->qdisc_list);
++ qdisc->next = dev->qdisc_list;
++ dev->qdisc_list = qdisc;
+ write_unlock(&qdisc_tree_lock);
+-
+ } else {
+ qdisc = &noqueue_qdisc;
+ }
+@@ -508,7 +518,7 @@
+ dev->qdisc = &noop_qdisc;
+ spin_unlock_bh(&dev->queue_lock);
+ dev->qdisc_sleeping = &noop_qdisc;
+- INIT_LIST_HEAD(&dev->qdisc_list);
++ dev->qdisc_list = NULL;
+ write_unlock(&qdisc_tree_lock);
+
+ dev_watchdog_init(dev);
+@@ -530,7 +540,7 @@
+ qdisc_destroy(qdisc);
+ }
+ #endif
+- BUG_TRAP(list_empty(&dev->qdisc_list));
++ BUG_TRAP(dev->qdisc_list == NULL);
+ BUG_TRAP(!timer_pending(&dev->watchdog_timer));
+ spin_unlock_bh(&dev->queue_lock);
+ write_unlock(&qdisc_tree_lock);