diff -Nur linux-2.4.30/include/linux/netdevice.h linux-2.4.30-wl-fix/include/linux/netdevice.h
--- linux-2.4.30/include/linux/netdevice.h	2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl-fix/include/linux/netdevice.h	2005-05-09 16:31:08.000000000 +0200
@@ -297,7 +297,7 @@
 	 * See <net/iw_handler.h> for details. Jean II */
 	struct iw_handler_def *	wireless_handlers;
 
-	struct ethtool_ops *ethtool_ops;
+
 
 	/*
 	 * This marks the end of the "visible" part of the structure. All
@@ -352,8 +355,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 */
@@ -453,6 +460,7 @@
 	/* this will get initialized at each interface type init routine */
 	struct divert_blk	*divert;
 #endif /* CONFIG_NET_DIVERT */
+	struct ethtool_ops *ethtool_ops;
 };
 
 /* 2.6 compatibility */
diff -Nur linux-2.4.30/include/linux/skbuff.h linux-2.4.30-wl-fix/include/linux/skbuff.h
--- linux-2.4.30/include/linux/skbuff.h	2005-04-04 03:42:20.000000000 +0200
+++ linux-2.4.30-wl-fix/include/linux/skbuff.h	2005-05-08 00:50:55.000000000 +0200
@@ -135,10 +135,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
@@ -219,6 +215,10 @@
 #ifdef CONFIG_NET_SCHED
        __u32           tc_index;               /* traffic control index */
 #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 -Nur linux-2.4.30/include/net/pkt_sched.h linux-2.4.30-wl-fix/include/net/pkt_sched.h
--- linux-2.4.30/include/net/pkt_sched.h	2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl-fix/include/net/pkt_sched.h	2005-05-08 01:05:48.000000000 +0200
@@ -59,8 +59,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 *);
@@ -80,12 +83,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 -Nur linux-2.4.30/net/core/dev.c linux-2.4.30-wl-fix/net/core/dev.c
--- linux-2.4.30/net/core/dev.c	2005-04-04 03:42:20.000000000 +0200
+++ linux-2.4.30-wl-fix/net/core/dev.c	2005-05-08 00:51:08.000000000 +0200
@@ -2311,6 +2311,7 @@
 			}
 			return ret;
 
+#ifndef CONFIG_BCM4710
 		case SIOCETHTOOL:
 			dev_load(ifr.ifr_name);
 			rtnl_lock();
@@ -2324,6 +2325,7 @@
 					ret = -EFAULT;
 			}
 			return ret;
+#endif
 
 		/*
 		 *	These ioctl calls:
diff -Nur linux-2.4.30/net/core/Makefile linux-2.4.30-wl-fix/net/core/Makefile
--- linux-2.4.30/net/core/Makefile	2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl-fix/net/core/Makefile	2005-05-08 00:51:02.000000000 +0200
@@ -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 -Nur linux-2.4.30/net/sched/sch_api.c linux-2.4.30-wl-fix/net/sched/sch_api.c
--- linux-2.4.30/net/sched/sch_api.c	2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl-fix/net/sched/sch_api.c	2005-05-08 00:51:14.000000000 +0200
@@ -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 -Nur linux-2.4.30/net/sched/sch_generic.c linux-2.4.30-wl-fix/net/sched/sch_generic.c
--- linux-2.4.30/net/sched/sch_generic.c	2004-11-17 12:54:22.000000000 +0100
+++ linux-2.4.30-wl-fix/net/sched/sch_generic.c	2005-05-08 00:51:20.000000000 +0200
@@ -392,7 +392,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;
@@ -422,11 +421,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
@@ -455,9 +465,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;
 		}
@@ -501,7 +511,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);
@@ -523,7 +533,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);
diff -urN linux.old/net/core/dev.c linux.dev/net/core/dev.c
--- linux.old/net/core/dev.c	2005-05-28 17:42:07.000000000 +0200
+++ linux.dev/net/core/dev.c	2005-05-28 20:38:06.000000000 +0200
@@ -2223,6 +2223,7 @@
 			    cmd == SIOCGMIIPHY ||
 			    cmd == SIOCGMIIREG ||
 			    cmd == SIOCSMIIREG ||
+			    cmd == SIOCETHTOOL ||
 			    cmd == SIOCWANDEV) {
 				if (dev->do_ioctl) {
 					if (!netif_device_present(dev))
@@ -2405,6 +2406,7 @@
 		 
 		default:
 			if (cmd == SIOCWANDEV ||
+			    (cmd == SIOCETHTOOL) ||
 			    (cmd >= SIOCDEVPRIVATE &&
 			     cmd <= SIOCDEVPRIVATE + 15)) {
 				dev_load(ifr.ifr_name);
