brcmutil: add dequeue function with filtering
authorArend van Spriel <arend@broadcom.com>
Sun, 3 Mar 2013 11:45:31 +0000 (12:45 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 6 Mar 2013 21:28:48 +0000 (16:28 -0500)
Adding a packet dequeue function that will return packets that
pass the provided match function.

Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Piotr Haber <phaber@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/brcm80211/brcmutil/utils.c
drivers/net/wireless/brcm80211/include/brcmu_utils.h

index 3e6405e..bf5e50f 100644 (file)
@@ -116,6 +116,31 @@ struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
 }
 EXPORT_SYMBOL(brcmu_pktq_pdeq);
 
+/*
+ * precedence based dequeue with match function. Passing a NULL pointer
+ * for the match function parameter is considered to be a wildcard so
+ * any packet on the queue is returned. In that case it is no different
+ * from brcmu_pktq_pdeq() above.
+ */
+struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
+                                     bool (*match_fn)(struct sk_buff *skb,
+                                                      void *arg), void *arg)
+{
+       struct sk_buff_head *q;
+       struct sk_buff *p, *next;
+
+       q = &pq->q[prec].skblist;
+       skb_queue_walk_safe(q, p, next) {
+               if (match_fn == NULL || match_fn(p, arg)) {
+                       skb_unlink(p, q);
+                       pq->len--;
+                       return p;
+               }
+       }
+       return NULL;
+}
+EXPORT_SYMBOL(brcmu_pktq_pdeq_match);
+
 struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
 {
        struct sk_buff_head *q;
index 82fcfe8..898cacb 100644 (file)
@@ -120,6 +120,10 @@ extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
                                      struct sk_buff *p);
 extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec);
 extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec);
+extern struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec,
+                                            bool (*match_fn)(struct sk_buff *p,
+                                                             void *arg),
+                                            void *arg);
 
 /* packet primitives */
 extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len);