aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2011-11-10 14:30:27 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-11 14:28:40 -0500
commitad3b8b39189689dbff84c8a8edf024511b087f87 (patch)
tree533b37b0b1e4fb219bf9f854f4d193e3f1ea199e
parentad4d71f69ebe2acab75d0a8a66ab9f7609151cce (diff)
brcm80211: util: use sk_buff_head in precedence queue functions
Instead of dealing with sk_buff prev pointers the queue functions now make use of the sk_buff_head functions provided by the kernel. Reported-by: Johannes Berg <johannes@sipsolutions.net> Reviewed-by: Alwin Beukers <alwin@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/utils.c121
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_utils.h16
2 files changed, 39 insertions, 98 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 12b795ffd369..57e656f987ad 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -86,21 +86,13 @@ EXPORT_SYMBOL(brcmu_pkttotlen);
86struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, 86struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,
87 struct sk_buff *p) 87 struct sk_buff *p)
88{ 88{
89 struct pktq_prec *q; 89 struct sk_buff_head *q;
90 90
91 if (pktq_full(pq) || pktq_pfull(pq, prec)) 91 if (pktq_full(pq) || pktq_pfull(pq, prec))
92 return NULL; 92 return NULL;
93 93
94 q = &pq->q[prec]; 94 q = &pq->q[prec].skblist;
95 95 skb_queue_tail(q, p);
96 if (q->head)
97 q->tail->prev = p;
98 else
99 q->head = p;
100
101 q->tail = p;
102 q->len++;
103
104 pq->len++; 96 pq->len++;
105 97
106 if (pq->hi_prec < prec) 98 if (pq->hi_prec < prec)
@@ -113,20 +105,13 @@ EXPORT_SYMBOL(brcmu_pktq_penq);
113struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, 105struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec,
114 struct sk_buff *p) 106 struct sk_buff *p)
115{ 107{
116 struct pktq_prec *q; 108 struct sk_buff_head *q;
117 109
118 if (pktq_full(pq) || pktq_pfull(pq, prec)) 110 if (pktq_full(pq) || pktq_pfull(pq, prec))
119 return NULL; 111 return NULL;
120 112
121 q = &pq->q[prec]; 113 q = &pq->q[prec].skblist;
122 114 skb_queue_head(q, p);
123 if (q->head == NULL)
124 q->tail = p;
125
126 p->prev = q->head;
127 q->head = p;
128 q->len++;
129
130 pq->len++; 115 pq->len++;
131 116
132 if (pq->hi_prec < prec) 117 if (pq->hi_prec < prec)
@@ -138,53 +123,30 @@ EXPORT_SYMBOL(brcmu_pktq_penq_head);
138 123
139struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec) 124struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec)
140{ 125{
141 struct pktq_prec *q; 126 struct sk_buff_head *q;
142 struct sk_buff *p; 127 struct sk_buff *p;
143 128
144 q = &pq->q[prec]; 129 q = &pq->q[prec].skblist;
145 130 p = skb_dequeue(q);
146 p = q->head;
147 if (p == NULL) 131 if (p == NULL)
148 return NULL; 132 return NULL;
149 133
150 q->head = p->prev;
151 if (q->head == NULL)
152 q->tail = NULL;
153
154 q->len--;
155
156 pq->len--; 134 pq->len--;
157
158 p->prev = NULL;
159
160 return p; 135 return p;
161} 136}
162EXPORT_SYMBOL(brcmu_pktq_pdeq); 137EXPORT_SYMBOL(brcmu_pktq_pdeq);
163 138
164struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec) 139struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec)
165{ 140{
166 struct pktq_prec *q; 141 struct sk_buff_head *q;
167 struct sk_buff *p, *prev; 142 struct sk_buff *p;
168
169 q = &pq->q[prec];
170 143
171 p = q->head; 144 q = &pq->q[prec].skblist;
145 p = skb_dequeue_tail(q);
172 if (p == NULL) 146 if (p == NULL)
173 return NULL; 147 return NULL;
174 148
175 for (prev = NULL; p != q->tail; p = p->prev)
176 prev = p;
177
178 if (prev)
179 prev->prev = NULL;
180 else
181 q->head = NULL;
182
183 q->tail = prev;
184 q->len--;
185
186 pq->len--; 149 pq->len--;
187
188 return p; 150 return p;
189} 151}
190EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); 152EXPORT_SYMBOL(brcmu_pktq_pdeq_tail);
@@ -193,31 +155,17 @@ void
193brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, 155brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir,
194 bool (*fn)(struct sk_buff *, void *), void *arg) 156 bool (*fn)(struct sk_buff *, void *), void *arg)
195{ 157{
196 struct pktq_prec *q; 158 struct sk_buff_head *q;
197 struct sk_buff *p, *prev = NULL; 159 struct sk_buff *p, *next;
198 160
199 q = &pq->q[prec]; 161 q = &pq->q[prec].skblist;
200 p = q->head; 162 skb_queue_walk_safe(q, p, next) {
201 while (p) {
202 if (fn == NULL || (*fn) (p, arg)) { 163 if (fn == NULL || (*fn) (p, arg)) {
203 bool head = (p == q->head); 164 skb_unlink(p, q);
204 if (head)
205 q->head = p->prev;
206 else
207 prev->prev = p->prev;
208 p->prev = NULL;
209 brcmu_pkt_buf_free_skb(p); 165 brcmu_pkt_buf_free_skb(p);
210 q->len--;
211 pq->len--; 166 pq->len--;
212 p = (head ? q->head : prev->prev);
213 } else {
214 prev = p;
215 p = p->prev;
216 } 167 }
217 } 168 }
218
219 if (q->head == NULL)
220 q->tail = NULL;
221} 169}
222EXPORT_SYMBOL(brcmu_pktq_pflush); 170EXPORT_SYMBOL(brcmu_pktq_pflush);
223 171
@@ -242,8 +190,10 @@ void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len)
242 190
243 pq->max = (u16) max_len; 191 pq->max = (u16) max_len;
244 192
245 for (prec = 0; prec < num_prec; prec++) 193 for (prec = 0; prec < num_prec; prec++) {
246 pq->q[prec].max = pq->max; 194 pq->q[prec].max = pq->max;
195 skb_queue_head_init(&pq->q[prec].skblist);
196 }
247} 197}
248EXPORT_SYMBOL(brcmu_pktq_init); 198EXPORT_SYMBOL(brcmu_pktq_init);
249 199
@@ -255,13 +205,13 @@ struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out)
255 return NULL; 205 return NULL;
256 206
257 for (prec = 0; prec < pq->hi_prec; prec++) 207 for (prec = 0; prec < pq->hi_prec; prec++)
258 if (pq->q[prec].head) 208 if (!skb_queue_empty(&pq->q[prec].skblist))
259 break; 209 break;
260 210
261 if (prec_out) 211 if (prec_out)
262 *prec_out = prec; 212 *prec_out = prec;
263 213
264 return pq->q[prec].tail; 214 return skb_peek_tail(&pq->q[prec].skblist);
265} 215}
266EXPORT_SYMBOL(brcmu_pktq_peek_tail); 216EXPORT_SYMBOL(brcmu_pktq_peek_tail);
267 217
@@ -274,7 +224,7 @@ int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp)
274 224
275 for (prec = 0; prec <= pq->hi_prec; prec++) 225 for (prec = 0; prec <= pq->hi_prec; prec++)
276 if (prec_bmp & (1 << prec)) 226 if (prec_bmp & (1 << prec))
277 len += pq->q[prec].len; 227 len += pq->q[prec].skblist.qlen;
278 228
279 return len; 229 return len;
280} 230}
@@ -284,39 +234,32 @@ EXPORT_SYMBOL(brcmu_pktq_mlen);
284struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, 234struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp,
285 int *prec_out) 235 int *prec_out)
286{ 236{
287 struct pktq_prec *q; 237 struct sk_buff_head *q;
288 struct sk_buff *p; 238 struct sk_buff *p;
289 int prec; 239 int prec;
290 240
291 if (pq->len == 0) 241 if (pq->len == 0)
292 return NULL; 242 return NULL;
293 243
294 while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) 244 while ((prec = pq->hi_prec) > 0 &&
245 skb_queue_empty(&pq->q[prec].skblist))
295 pq->hi_prec--; 246 pq->hi_prec--;
296 247
297 while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) 248 while ((prec_bmp & (1 << prec)) == 0 ||
249 skb_queue_empty(&pq->q[prec].skblist))
298 if (prec-- == 0) 250 if (prec-- == 0)
299 return NULL; 251 return NULL;
300 252
301 q = &pq->q[prec]; 253 q = &pq->q[prec].skblist;
302 254 p = skb_dequeue(q);
303 p = q->head;
304 if (p == NULL) 255 if (p == NULL)
305 return NULL; 256 return NULL;
306 257
307 q->head = p->prev; 258 pq->len--;
308 if (q->head == NULL)
309 q->tail = NULL;
310
311 q->len--;
312 259
313 if (prec_out) 260 if (prec_out)
314 *prec_out = prec; 261 *prec_out = prec;
315 262
316 pq->len--;
317
318 p->prev = NULL;
319
320 return p; 263 return p;
321} 264}
322EXPORT_SYMBOL(brcmu_pktq_mdeq); 265EXPORT_SYMBOL(brcmu_pktq_mdeq);
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index ccf60151953c..cae4e519d187 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -65,9 +65,7 @@
65#define ETHER_ADDR_STR_LEN 18 65#define ETHER_ADDR_STR_LEN 18
66 66
67struct pktq_prec { 67struct pktq_prec {
68 struct sk_buff *head; /* first packet to dequeue */ 68 struct sk_buff_head skblist;
69 struct sk_buff *tail; /* last packet to dequeue */
70 u16 len; /* number of queued packets */
71 u16 max; /* maximum number of queued packets */ 69 u16 max; /* maximum number of queued packets */
72}; 70};
73 71
@@ -88,32 +86,32 @@ struct pktq {
88 86
89static inline int pktq_plen(struct pktq *pq, int prec) 87static inline int pktq_plen(struct pktq *pq, int prec)
90{ 88{
91 return pq->q[prec].len; 89 return pq->q[prec].skblist.qlen;
92} 90}
93 91
94static inline int pktq_pavail(struct pktq *pq, int prec) 92static inline int pktq_pavail(struct pktq *pq, int prec)
95{ 93{
96 return pq->q[prec].max - pq->q[prec].len; 94 return pq->q[prec].max - pq->q[prec].skblist.qlen;
97} 95}
98 96
99static inline bool pktq_pfull(struct pktq *pq, int prec) 97static inline bool pktq_pfull(struct pktq *pq, int prec)
100{ 98{
101 return pq->q[prec].len >= pq->q[prec].max; 99 return pq->q[prec].skblist.qlen >= pq->q[prec].max;
102} 100}
103 101
104static inline bool pktq_pempty(struct pktq *pq, int prec) 102static inline bool pktq_pempty(struct pktq *pq, int prec)
105{ 103{
106 return pq->q[prec].len == 0; 104 return skb_queue_empty(&pq->q[prec].skblist);
107} 105}
108 106
109static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec) 107static inline struct sk_buff *pktq_ppeek(struct pktq *pq, int prec)
110{ 108{
111 return pq->q[prec].head; 109 return skb_peek(&pq->q[prec].skblist);
112} 110}
113 111
114static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) 112static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec)
115{ 113{
116 return pq->q[prec].tail; 114 return skb_peek_tail(&pq->q[prec].skblist);
117} 115}
118 116
119extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, 117extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec,