mac80211: move TX info into skb->cb
[linux-2.6.git] / net / mac80211 / wme.c
1 /*
2  * Copyright 2004, Instant802 Networks, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include <linux/netdevice.h>
10 #include <linux/skbuff.h>
11 #include <linux/module.h>
12 #include <linux/if_arp.h>
13 #include <linux/types.h>
14 #include <net/ip.h>
15 #include <net/pkt_sched.h>
16
17 #include <net/mac80211.h>
18 #include "ieee80211_i.h"
19 #include "wme.h"
20
21 /* maximum number of hardware queues we support. */
22 #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
23 /* current number of hardware queues we support. */
24 #define QD_NUM(hw) ((hw)->queues + (hw)->ampdu_queues)
25
26 /*
27  * Default mapping in classifier to work with default
28  * queue setup.
29  */
30 const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
31
32 struct ieee80211_sched_data
33 {
34         unsigned long qdisc_pool[BITS_TO_LONGS(QD_MAX_QUEUES)];
35         struct tcf_proto *filter_list;
36         struct Qdisc *queues[QD_MAX_QUEUES];
37         struct sk_buff_head requeued[QD_MAX_QUEUES];
38 };
39
40 static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0};
41
42 /* given a data frame determine the 802.1p/1d tag to use */
43 static inline unsigned classify_1d(struct sk_buff *skb, struct Qdisc *qd)
44 {
45         struct iphdr *ip;
46         int dscp;
47         int offset;
48
49         struct ieee80211_sched_data *q = qdisc_priv(qd);
50         struct tcf_result res = { -1, 0 };
51
52         /* if there is a user set filter list, call out to that */
53         if (q->filter_list) {
54                 tc_classify(skb, q->filter_list, &res);
55                 if (res.class != -1)
56                         return res.class;
57         }
58
59         /* skb->priority values from 256->263 are magic values to
60          * directly indicate a specific 802.1d priority.
61          * This is used to allow 802.1d priority to be passed directly in
62          * from VLAN tags, etc. */
63         if (skb->priority >= 256 && skb->priority <= 263)
64                 return skb->priority - 256;
65
66         /* check there is a valid IP header present */
67         offset = ieee80211_get_hdrlen_from_skb(skb);
68         if (skb->len < offset + sizeof(llc_ip_hdr) + sizeof(*ip) ||
69             memcmp(skb->data + offset, llc_ip_hdr, sizeof(llc_ip_hdr)))
70                 return 0;
71
72         ip = (struct iphdr *) (skb->data + offset + sizeof(llc_ip_hdr));
73
74         dscp = ip->tos & 0xfc;
75         if (dscp & 0x1c)
76                 return 0;
77         return dscp >> 5;
78 }
79
80
81 static inline int wme_downgrade_ac(struct sk_buff *skb)
82 {
83         switch (skb->priority) {
84         case 6:
85         case 7:
86                 skb->priority = 5; /* VO -> VI */
87                 return 0;
88         case 4:
89         case 5:
90                 skb->priority = 3; /* VI -> BE */
91                 return 0;
92         case 0:
93         case 3:
94                 skb->priority = 2; /* BE -> BK */
95                 return 0;
96         default:
97                 return -1;
98         }
99 }
100
101
102 /* positive return value indicates which queue to use
103  * negative return value indicates to drop the frame */
104 static int classify80211(struct sk_buff *skb, struct Qdisc *qd)
105 {
106         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
107         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
108         unsigned short fc = le16_to_cpu(hdr->frame_control);
109         int qos;
110
111         /* see if frame is data or non data frame */
112         if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) {
113                 /* management frames go on AC_VO queue, but are sent
114                 * without QoS control fields */
115                 return 0;
116         }
117
118         if (0 /* injected */) {
119                 /* use AC from radiotap */
120         }
121
122         /* is this a QoS frame? */
123         qos = fc & IEEE80211_STYPE_QOS_DATA;
124
125         if (!qos) {
126                 skb->priority = 0; /* required for correct WPA/11i MIC */
127                 return ieee802_1d_to_ac[skb->priority];
128         }
129
130         /* use the data classifier to determine what 802.1d tag the
131          * data frame has */
132         skb->priority = classify_1d(skb, qd);
133
134         /* in case we are a client verify acm is not set for this ac */
135         while (unlikely(local->wmm_acm & BIT(skb->priority))) {
136                 if (wme_downgrade_ac(skb)) {
137                         /* No AC with lower priority has acm=0, drop packet. */
138                         return -1;
139                 }
140         }
141
142         /* look up which queue to use for frames with this 1d tag */
143         return ieee802_1d_to_ac[skb->priority];
144 }
145
146
147 static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd)
148 {
149         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
150         struct ieee80211_hw *hw = &local->hw;
151         struct ieee80211_sched_data *q = qdisc_priv(qd);
152         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
153         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
154         unsigned short fc = le16_to_cpu(hdr->frame_control);
155         struct Qdisc *qdisc;
156         struct sta_info *sta;
157         int err, queue;
158         u8 tid;
159
160         if (info->flags & IEEE80211_TX_CTL_REQUEUE) {
161                 queue = info->queue;
162                 rcu_read_lock();
163                 sta = sta_info_get(local, hdr->addr1);
164                 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
165                 if (sta) {
166                         int ampdu_queue = sta->tid_to_tx_q[tid];
167                         if ((ampdu_queue < QD_NUM(hw)) &&
168                             test_bit(ampdu_queue, q->qdisc_pool)) {
169                                 queue = ampdu_queue;
170                                 info->flags |= IEEE80211_TX_CTL_AMPDU;
171                         } else {
172                                 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
173                         }
174                 }
175                 rcu_read_unlock();
176                 skb_queue_tail(&q->requeued[queue], skb);
177                 qd->q.qlen++;
178                 return 0;
179         }
180
181         queue = classify80211(skb, qd);
182
183         if (unlikely(queue >= local->hw.queues))
184                 queue = local->hw.queues - 1;
185
186         /* now we know the 1d priority, fill in the QoS header if there is one
187          */
188         if (WLAN_FC_IS_QOS_DATA(fc)) {
189                 u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2;
190                 u8 ack_policy = 0;
191                 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
192                 if (local->wifi_wme_noack_test)
193                         ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
194                                         QOS_CONTROL_ACK_POLICY_SHIFT;
195                 /* qos header is 2 bytes, second reserved */
196                 *p = ack_policy | tid;
197                 p++;
198                 *p = 0;
199
200                 rcu_read_lock();
201
202                 sta = sta_info_get(local, hdr->addr1);
203                 if (sta) {
204                         int ampdu_queue = sta->tid_to_tx_q[tid];
205                         if ((ampdu_queue < QD_NUM(hw)) &&
206                             test_bit(ampdu_queue, q->qdisc_pool)) {
207                                 queue = ampdu_queue;
208                                 info->flags |= IEEE80211_TX_CTL_AMPDU;
209                         } else {
210                                 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
211                         }
212                 }
213
214                 rcu_read_unlock();
215         }
216
217         if (unlikely(queue < 0)) {
218                         kfree_skb(skb);
219                         err = NET_XMIT_DROP;
220         } else {
221                 tid = skb->priority & QOS_CONTROL_TAG1D_MASK;
222                 info->queue = (unsigned int) queue;
223                 qdisc = q->queues[queue];
224                 err = qdisc->enqueue(skb, qdisc);
225                 if (err == NET_XMIT_SUCCESS) {
226                         qd->q.qlen++;
227                         qd->bstats.bytes += skb->len;
228                         qd->bstats.packets++;
229                         return NET_XMIT_SUCCESS;
230                 }
231         }
232         qd->qstats.drops++;
233         return err;
234 }
235
236
237 /* TODO: clean up the cases where master_hard_start_xmit
238  * returns non 0 - it shouldn't ever do that. Once done we
239  * can remove this function */
240 static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd)
241 {
242         struct ieee80211_sched_data *q = qdisc_priv(qd);
243         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
244         struct Qdisc *qdisc;
245         int err;
246
247         /* we recorded which queue to use earlier! */
248         qdisc = q->queues[info->queue];
249
250         if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) {
251                 qd->q.qlen++;
252                 return 0;
253         }
254         qd->qstats.drops++;
255         return err;
256 }
257
258
259 static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd)
260 {
261         struct ieee80211_sched_data *q = qdisc_priv(qd);
262         struct net_device *dev = qd->dev;
263         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
264         struct ieee80211_hw *hw = &local->hw;
265         struct sk_buff *skb;
266         struct Qdisc *qdisc;
267         int queue;
268
269         /* check all the h/w queues in numeric/priority order */
270         for (queue = 0; queue < QD_NUM(hw); queue++) {
271                 /* see if there is room in this hardware queue */
272                 if ((test_bit(IEEE80211_LINK_STATE_XOFF,
273                                 &local->state[queue])) ||
274                     (test_bit(IEEE80211_LINK_STATE_PENDING,
275                                 &local->state[queue])) ||
276                          (!test_bit(queue, q->qdisc_pool)))
277                         continue;
278
279                 /* there is space - try and get a frame */
280                 skb = skb_dequeue(&q->requeued[queue]);
281                 if (skb) {
282                         qd->q.qlen--;
283                         return skb;
284                 }
285
286                 qdisc = q->queues[queue];
287                 skb = qdisc->dequeue(qdisc);
288                 if (skb) {
289                         qd->q.qlen--;
290                         return skb;
291                 }
292         }
293         /* returning a NULL here when all the h/w queues are full means we
294          * never need to call netif_stop_queue in the driver */
295         return NULL;
296 }
297
298
299 static void wme_qdiscop_reset(struct Qdisc* qd)
300 {
301         struct ieee80211_sched_data *q = qdisc_priv(qd);
302         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
303         struct ieee80211_hw *hw = &local->hw;
304         int queue;
305
306         /* QUESTION: should we have some hardware flush functionality here? */
307
308         for (queue = 0; queue < QD_NUM(hw); queue++) {
309                 skb_queue_purge(&q->requeued[queue]);
310                 qdisc_reset(q->queues[queue]);
311         }
312         qd->q.qlen = 0;
313 }
314
315
316 static void wme_qdiscop_destroy(struct Qdisc* qd)
317 {
318         struct ieee80211_sched_data *q = qdisc_priv(qd);
319         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
320         struct ieee80211_hw *hw = &local->hw;
321         int queue;
322
323         tcf_destroy_chain(q->filter_list);
324         q->filter_list = NULL;
325
326         for (queue = 0; queue < QD_NUM(hw); queue++) {
327                 skb_queue_purge(&q->requeued[queue]);
328                 qdisc_destroy(q->queues[queue]);
329                 q->queues[queue] = &noop_qdisc;
330         }
331 }
332
333
334 /* called whenever parameters are updated on existing qdisc */
335 static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt)
336 {
337         return 0;
338 }
339
340
341 /* called during initial creation of qdisc on device */
342 static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt)
343 {
344         struct ieee80211_sched_data *q = qdisc_priv(qd);
345         struct net_device *dev = qd->dev;
346         struct ieee80211_local *local;
347         struct ieee80211_hw *hw;
348         int err = 0, i;
349
350         /* check that device is a mac80211 device */
351         if (!dev->ieee80211_ptr ||
352             dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid)
353                 return -EINVAL;
354
355         local = wdev_priv(dev->ieee80211_ptr);
356         hw = &local->hw;
357
358         /* only allow on master dev */
359         if (dev != local->mdev)
360                 return -EINVAL;
361
362         /* ensure that we are root qdisc */
363         if (qd->parent != TC_H_ROOT)
364                 return -EINVAL;
365
366         if (qd->flags & TCQ_F_INGRESS)
367                 return -EINVAL;
368
369         /* if options were passed in, set them */
370         if (opt)
371                 err = wme_qdiscop_tune(qd, opt);
372
373         /* create child queues */
374         for (i = 0; i < QD_NUM(hw); i++) {
375                 skb_queue_head_init(&q->requeued[i]);
376                 q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops,
377                                                  qd->handle);
378                 if (!q->queues[i]) {
379                         q->queues[i] = &noop_qdisc;
380                         printk(KERN_ERR "%s child qdisc %i creation failed\n",
381                                dev->name, i);
382                 }
383         }
384
385         /* non-aggregation queues: reserve/mark as used */
386         for (i = 0; i < local->hw.queues; i++)
387                 set_bit(i, q->qdisc_pool);
388
389         return err;
390 }
391
392 static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb)
393 {
394         return -1;
395 }
396
397
398 static int wme_classop_graft(struct Qdisc *qd, unsigned long arg,
399                              struct Qdisc *new, struct Qdisc **old)
400 {
401         struct ieee80211_sched_data *q = qdisc_priv(qd);
402         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
403         struct ieee80211_hw *hw = &local->hw;
404         unsigned long queue = arg - 1;
405
406         if (queue >= QD_NUM(hw))
407                 return -EINVAL;
408
409         if (!new)
410                 new = &noop_qdisc;
411
412         sch_tree_lock(qd);
413         *old = q->queues[queue];
414         q->queues[queue] = new;
415         qdisc_reset(*old);
416         sch_tree_unlock(qd);
417
418         return 0;
419 }
420
421
422 static struct Qdisc *
423 wme_classop_leaf(struct Qdisc *qd, unsigned long arg)
424 {
425         struct ieee80211_sched_data *q = qdisc_priv(qd);
426         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
427         struct ieee80211_hw *hw = &local->hw;
428         unsigned long queue = arg - 1;
429
430         if (queue >= QD_NUM(hw))
431                 return NULL;
432
433         return q->queues[queue];
434 }
435
436
437 static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid)
438 {
439         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
440         struct ieee80211_hw *hw = &local->hw;
441         unsigned long queue = TC_H_MIN(classid);
442
443         if (queue - 1 >= QD_NUM(hw))
444                 return 0;
445
446         return queue;
447 }
448
449
450 static unsigned long wme_classop_bind(struct Qdisc *qd, unsigned long parent,
451                                       u32 classid)
452 {
453         return wme_classop_get(qd, classid);
454 }
455
456
457 static void wme_classop_put(struct Qdisc *q, unsigned long cl)
458 {
459 }
460
461
462 static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent,
463                               struct nlattr **tca, unsigned long *arg)
464 {
465         unsigned long cl = *arg;
466         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
467         struct ieee80211_hw *hw = &local->hw;
468
469         if (cl - 1 > QD_NUM(hw))
470                 return -ENOENT;
471
472         /* TODO: put code to program hardware queue parameters here,
473          * to allow programming from tc command line */
474
475         return 0;
476 }
477
478
479 /* we don't support deleting hardware queues
480  * when we add WMM-SA support - TSPECs may be deleted here */
481 static int wme_classop_delete(struct Qdisc *qd, unsigned long cl)
482 {
483         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
484         struct ieee80211_hw *hw = &local->hw;
485
486         if (cl - 1 > QD_NUM(hw))
487                 return -ENOENT;
488         return 0;
489 }
490
491
492 static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl,
493                                   struct sk_buff *skb, struct tcmsg *tcm)
494 {
495         struct ieee80211_sched_data *q = qdisc_priv(qd);
496         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
497         struct ieee80211_hw *hw = &local->hw;
498
499         if (cl - 1 > QD_NUM(hw))
500                 return -ENOENT;
501         tcm->tcm_handle = TC_H_MIN(cl);
502         tcm->tcm_parent = qd->handle;
503         tcm->tcm_info = q->queues[cl-1]->handle; /* do we need this? */
504         return 0;
505 }
506
507
508 static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg)
509 {
510         struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr);
511         struct ieee80211_hw *hw = &local->hw;
512         int queue;
513
514         if (arg->stop)
515                 return;
516
517         for (queue = 0; queue < QD_NUM(hw); queue++) {
518                 if (arg->count < arg->skip) {
519                         arg->count++;
520                         continue;
521                 }
522                 /* we should return classids for our internal queues here
523                  * as well as the external ones */
524                 if (arg->fn(qd, queue+1, arg) < 0) {
525                         arg->stop = 1;
526                         break;
527                 }
528                 arg->count++;
529         }
530 }
531
532
533 static struct tcf_proto ** wme_classop_find_tcf(struct Qdisc *qd,
534                                                 unsigned long cl)
535 {
536         struct ieee80211_sched_data *q = qdisc_priv(qd);
537
538         if (cl)
539                 return NULL;
540
541         return &q->filter_list;
542 }
543
544
545 /* this qdisc is classful (i.e. has classes, some of which may have leaf qdiscs attached)
546  * - these are the operations on the classes */
547 static const struct Qdisc_class_ops class_ops =
548 {
549         .graft = wme_classop_graft,
550         .leaf = wme_classop_leaf,
551
552         .get = wme_classop_get,
553         .put = wme_classop_put,
554         .change = wme_classop_change,
555         .delete = wme_classop_delete,
556         .walk = wme_classop_walk,
557
558         .tcf_chain = wme_classop_find_tcf,
559         .bind_tcf = wme_classop_bind,
560         .unbind_tcf = wme_classop_put,
561
562         .dump = wme_classop_dump_class,
563 };
564
565
566 /* queueing discipline operations */
567 static struct Qdisc_ops wme_qdisc_ops __read_mostly =
568 {
569         .next = NULL,
570         .cl_ops = &class_ops,
571         .id = "ieee80211",
572         .priv_size = sizeof(struct ieee80211_sched_data),
573
574         .enqueue = wme_qdiscop_enqueue,
575         .dequeue = wme_qdiscop_dequeue,
576         .requeue = wme_qdiscop_requeue,
577         .drop = NULL, /* drop not needed since we are always the root qdisc */
578
579         .init = wme_qdiscop_init,
580         .reset = wme_qdiscop_reset,
581         .destroy = wme_qdiscop_destroy,
582         .change = wme_qdiscop_tune,
583
584         .dump = wme_qdiscop_dump,
585 };
586
587
588 void ieee80211_install_qdisc(struct net_device *dev)
589 {
590         struct Qdisc *qdisc;
591
592         qdisc = qdisc_create_dflt(dev, &wme_qdisc_ops, TC_H_ROOT);
593         if (!qdisc) {
594                 printk(KERN_ERR "%s: qdisc installation failed\n", dev->name);
595                 return;
596         }
597
598         /* same handle as would be allocated by qdisc_alloc_handle() */
599         qdisc->handle = 0x80010000;
600
601         qdisc_lock_tree(dev);
602         list_add_tail(&qdisc->list, &dev->qdisc_list);
603         dev->qdisc_sleeping = qdisc;
604         qdisc_unlock_tree(dev);
605 }
606
607
608 int ieee80211_qdisc_installed(struct net_device *dev)
609 {
610         return dev->qdisc_sleeping->ops == &wme_qdisc_ops;
611 }
612
613
614 int ieee80211_wme_register(void)
615 {
616         return register_qdisc(&wme_qdisc_ops);
617 }
618
619
620 void ieee80211_wme_unregister(void)
621 {
622         unregister_qdisc(&wme_qdisc_ops);
623 }
624
625 int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
626                         struct sta_info *sta, u16 tid)
627 {
628         int i;
629         struct ieee80211_sched_data *q =
630                         qdisc_priv(local->mdev->qdisc_sleeping);
631         DECLARE_MAC_BUF(mac);
632
633         /* prepare the filter and save it for the SW queue
634          * matching the received HW queue */
635
636         if (!local->hw.ampdu_queues)
637                 return -EPERM;
638
639         /* try to get a Qdisc from the pool */
640         for (i = local->hw.queues; i < QD_NUM(&local->hw); i++)
641                 if (!test_and_set_bit(i, q->qdisc_pool)) {
642                         ieee80211_stop_queue(local_to_hw(local), i);
643                         sta->tid_to_tx_q[tid] = i;
644
645                         /* IF there are already pending packets
646                          * on this tid first we need to drain them
647                          * on the previous queue
648                          * since HT is strict in order */
649 #ifdef CONFIG_MAC80211_HT_DEBUG
650                         if (net_ratelimit())
651                                 printk(KERN_DEBUG "allocated aggregation queue"
652                                         " %d tid %d addr %s pool=0x%lX",
653                                         i, tid, print_mac(mac, sta->addr),
654                                         q->qdisc_pool[0]);
655 #endif /* CONFIG_MAC80211_HT_DEBUG */
656                         return 0;
657                 }
658
659         return -EAGAIN;
660 }
661
662 /**
663  * the caller needs to hold local->mdev->queue_lock
664  */
665 void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local,
666                                    struct sta_info *sta, u16 tid,
667                                    u8 requeue)
668 {
669         struct ieee80211_hw *hw = &local->hw;
670         struct ieee80211_sched_data *q =
671                 qdisc_priv(local->mdev->qdisc_sleeping);
672         int agg_queue = sta->tid_to_tx_q[tid];
673
674         /* return the qdisc to the pool */
675         clear_bit(agg_queue, q->qdisc_pool);
676         sta->tid_to_tx_q[tid] = QD_NUM(hw);
677
678         if (requeue)
679                 ieee80211_requeue(local, agg_queue);
680         else
681                 q->queues[agg_queue]->ops->reset(q->queues[agg_queue]);
682 }
683
684 void ieee80211_requeue(struct ieee80211_local *local, int queue)
685 {
686         struct Qdisc *root_qd = local->mdev->qdisc_sleeping;
687         struct ieee80211_sched_data *q = qdisc_priv(root_qd);
688         struct Qdisc *qdisc = q->queues[queue];
689         struct sk_buff *skb = NULL;
690         u32 len;
691
692         if (!qdisc || !qdisc->dequeue)
693                 return;
694
695         printk(KERN_DEBUG "requeue: qlen = %d\n", qdisc->q.qlen);
696         for (len = qdisc->q.qlen; len > 0; len--) {
697                 skb = qdisc->dequeue(qdisc);
698                 root_qd->q.qlen--;
699                 /* packet will be classified again and */
700                 /* skb->packet_data->queue will be overridden if needed */
701                 if (skb)
702                         wme_qdiscop_enqueue(skb, root_qd);
703         }
704 }