generic: ar8216: fix phy driver name
[openwrt.git] / target / linux / generic / patches-2.6.30 / 260-extend_pfifo_fast.patch
1 --- a/net/sched/sch_generic.c
2 +++ b/net/sched/sch_generic.c
3 @@ -371,16 +371,50 @@ static const u8 prio2band[TC_PRIO_MAX+1]
4  
5  #define PFIFO_FAST_BANDS 3
6  
7 +struct pfifo_fast_sched_data {
8 +       struct tcf_proto *filter_list;
9 +       struct sk_buff_head list[PFIFO_FAST_BANDS];
10 +};
11 +
12  static inline struct sk_buff_head *prio2list(struct sk_buff *skb,
13                                              struct Qdisc *qdisc)
14  {
15 -       struct sk_buff_head *list = qdisc_priv(qdisc);
16 +       struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
17 +       struct sk_buff_head *list = q->list;
18         return list + prio2band[skb->priority & TC_PRIO_MAX];
19  }
20  
21 +static int pfifo_fast_filter(struct sk_buff *skb, struct Qdisc* qdisc)
22 +{
23 +#ifdef CONFIG_NET_CLS_ACT
24 +       struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
25 +       int result = 0, ret = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
26 +       struct tcf_result res;
27 +
28 +       if (q->filter_list != NULL)
29 +               result = tc_classify(skb, q->filter_list, &res);
30 +       if (result >= 0) {
31 +               switch (result) {
32 +               case TC_ACT_STOLEN:
33 +               case TC_ACT_QUEUED:
34 +                       ret = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
35 +               case TC_ACT_SHOT:
36 +                       kfree_skb(skb);
37 +                       return ret;
38 +               }
39 +       }
40 +#endif
41 +       return 0;
42 +}
43 +
44  static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
45  {
46         struct sk_buff_head *list = prio2list(skb, qdisc);
47 +       int ret;
48 +
49 +       ret = pfifo_fast_filter(skb, qdisc);
50 +       if (ret)
51 +               return ret;
52  
53         if (skb_queue_len(list) < qdisc_dev(qdisc)->tx_queue_len) {
54                 qdisc->q.qlen++;
55 @@ -392,8 +426,9 @@ static int pfifo_fast_enqueue(struct sk_
56  
57  static struct sk_buff *pfifo_fast_dequeue(struct Qdisc* qdisc)
58  {
59 +       struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
60 +       struct sk_buff_head *list = q->list;
61         int prio;
62 -       struct sk_buff_head *list = qdisc_priv(qdisc);
63  
64         for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
65                 if (!skb_queue_empty(list + prio)) {
66 @@ -420,8 +455,9 @@ static struct sk_buff *pfifo_fast_peek(s
67  
68  static void pfifo_fast_reset(struct Qdisc* qdisc)
69  {
70 +       struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
71 +       struct sk_buff_head *list = q->list;
72         int prio;
73 -       struct sk_buff_head *list = qdisc_priv(qdisc);
74  
75         for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
76                 __qdisc_reset_queue(qdisc, list + prio);
77 @@ -444,8 +480,9 @@ nla_put_failure:
78  
79  static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
80  {
81 +       struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
82 +       struct sk_buff_head *list = q->list;
83         int prio;
84 -       struct sk_buff_head *list = qdisc_priv(qdisc);
85  
86         for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
87                 skb_queue_head_init(list + prio);
88 @@ -453,9 +490,36 @@ static int pfifo_fast_init(struct Qdisc 
89         return 0;
90  }
91  
92 +static int pfifo_fast_change_class(struct Qdisc *qdisc, u32 classid, u32 parentid,
93 +                           struct nlattr **tca, unsigned long *arg)
94 +{
95 +       return -EOPNOTSUPP;
96 +}
97 +
98 +static unsigned long pfifo_fast_get(struct Qdisc *qdisc, u32 classid)
99 +{
100 +       return 0;
101 +}
102 +
103 +static struct tcf_proto **pfifo_fast_find_tcf(struct Qdisc *qdisc, unsigned long cl)
104 +{
105 +       struct pfifo_fast_sched_data *q = qdisc_priv(qdisc);
106 +
107 +       if (cl)
108 +               return NULL;
109 +       return &q->filter_list;
110 +}
111 +
112 +static const struct Qdisc_class_ops pfifo_fast_class_ops = {
113 +       .get            =       pfifo_fast_get,
114 +       .change         =       pfifo_fast_change_class,
115 +       .tcf_chain      =       pfifo_fast_find_tcf,
116 +};
117 +
118  static struct Qdisc_ops pfifo_fast_ops __read_mostly = {
119         .id             =       "pfifo_fast",
120 -       .priv_size      =       PFIFO_FAST_BANDS * sizeof(struct sk_buff_head),
121 +       .cl_ops         =       &pfifo_fast_class_ops,
122 +       .priv_size      =       sizeof(struct pfifo_fast_sched_data),
123         .enqueue        =       pfifo_fast_enqueue,
124         .dequeue        =       pfifo_fast_dequeue,
125         .peek           =       pfifo_fast_peek,
126 @@ -735,3 +799,18 @@ void dev_shutdown(struct net_device *dev
127         shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
128         WARN_ON(timer_pending(&dev->watchdog_timer));
129  }
130 +
131 +#ifdef CONFIG_NET_SCHED
132 +static int __init sch_generic_init(void)
133 +{
134 +       return register_qdisc(&pfifo_fast_ops);
135 +}
136 +
137 +static void __exit sch_generic_exit(void)
138 +{
139 +       unregister_qdisc(&pfifo_fast_ops);
140 +}
141 +
142 +module_init(sch_generic_init)
143 +module_exit(sch_generic_exit)
144 +#endif