1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67#include <linux/netdevice.h>
68#include <linux/etherdevice.h>
69#include "i1480u-wlp.h"
70
71
72
73
74
75
76
77int i1480u_rx_setup(struct i1480u *i1480u)
78{
79 int result, cnt;
80 struct device *dev = &i1480u->usb_iface->dev;
81 struct net_device *net_dev = i1480u->net_dev;
82 struct usb_endpoint_descriptor *epd;
83 struct sk_buff *skb;
84
85
86 i1480u->rx_skb = NULL;
87 result = -ENOMEM;
88 epd = &i1480u->usb_iface->cur_altsetting->endpoint[1].desc;
89 for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
90 struct i1480u_rx_buf *rx_buf = &i1480u->rx_buf[cnt];
91 rx_buf->i1480u = i1480u;
92 skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE);
93 if (!skb) {
94 dev_err(dev,
95 "RX: cannot allocate RX buffer %d\n", cnt);
96 result = -ENOMEM;
97 goto error;
98 }
99 skb->dev = net_dev;
100 skb->ip_summed = CHECKSUM_NONE;
101 skb_reserve(skb, 2);
102 rx_buf->data = skb;
103 rx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
104 if (unlikely(rx_buf->urb == NULL)) {
105 dev_err(dev, "RX: cannot allocate URB %d\n", cnt);
106 result = -ENOMEM;
107 goto error;
108 }
109 usb_fill_bulk_urb(rx_buf->urb, i1480u->usb_dev,
110 usb_rcvbulkpipe(i1480u->usb_dev, epd->bEndpointAddress),
111 rx_buf->data->data, i1480u_MAX_RX_PKT_SIZE - 2,
112 i1480u_rx_cb, rx_buf);
113 result = usb_submit_urb(rx_buf->urb, GFP_NOIO);
114 if (unlikely(result < 0)) {
115 dev_err(dev, "RX: cannot submit URB %d: %d\n",
116 cnt, result);
117 goto error;
118 }
119 }
120 return 0;
121
122error:
123 i1480u_rx_release(i1480u);
124 return result;
125}
126
127
128
129void i1480u_rx_release(struct i1480u *i1480u)
130{
131 int cnt;
132 for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
133 if (i1480u->rx_buf[cnt].data)
134 dev_kfree_skb(i1480u->rx_buf[cnt].data);
135 if (i1480u->rx_buf[cnt].urb) {
136 usb_kill_urb(i1480u->rx_buf[cnt].urb);
137 usb_free_urb(i1480u->rx_buf[cnt].urb);
138 }
139 }
140 if (i1480u->rx_skb != NULL)
141 dev_kfree_skb(i1480u->rx_skb);
142}
143
144static
145void i1480u_rx_unlink_urbs(struct i1480u *i1480u)
146{
147 int cnt;
148 for (cnt = 0; cnt < i1480u_RX_BUFS; cnt++) {
149 if (i1480u->rx_buf[cnt].urb)
150 usb_unlink_urb(i1480u->rx_buf[cnt].urb);
151 }
152}
153
154
155#define i1480u_fix(i1480u, msg...) \
156do { \
157 if (printk_ratelimit()) \
158 dev_err(&i1480u->usb_iface->dev, msg); \
159 dev_kfree_skb_irq(i1480u->rx_skb); \
160 i1480u->rx_skb = NULL; \
161 i1480u->rx_untd_pkt_size = 0; \
162} while (0)
163
164
165
166#define i1480u_drop(i1480u, msg...) \
167do { \
168 if (printk_ratelimit()) \
169 dev_err(&i1480u->usb_iface->dev, msg); \
170 i1480u->net_dev->stats.rx_dropped++; \
171} while (0)
172
173
174
175
176
177
178
179
180
181
182
183
184static
185void i1480u_skb_deliver(struct i1480u *i1480u)
186{
187 int should_parse;
188 struct net_device *net_dev = i1480u->net_dev;
189 struct device *dev = &i1480u->usb_iface->dev;
190
191 should_parse = wlp_receive_frame(dev, &i1480u->wlp, i1480u->rx_skb,
192 &i1480u->rx_srcaddr);
193 if (!should_parse)
194 goto out;
195 i1480u->rx_skb->protocol = eth_type_trans(i1480u->rx_skb, net_dev);
196 net_dev->stats.rx_packets++;
197 net_dev->stats.rx_bytes += i1480u->rx_untd_pkt_size;
198
199 netif_rx(i1480u->rx_skb);
200out:
201 i1480u->rx_skb = NULL;
202 i1480u->rx_untd_pkt_size = 0;
203}
204
205
206
207
208
209
210
211
212
213
214static
215void i1480u_rx_buffer(struct i1480u_rx_buf *rx_buf)
216{
217 unsigned pkt_completed = 0;
218 size_t untd_hdr_size, untd_frg_size;
219 size_t i1480u_hdr_size;
220 struct wlp_rx_hdr *i1480u_hdr = NULL;
221
222 struct i1480u *i1480u = rx_buf->i1480u;
223 struct sk_buff *skb = rx_buf->data;
224 int size_left = rx_buf->urb->actual_length;
225 void *ptr = rx_buf->urb->transfer_buffer;
226 struct untd_hdr *untd_hdr;
227
228 struct net_device *net_dev = i1480u->net_dev;
229 struct device *dev = &i1480u->usb_iface->dev;
230 struct sk_buff *new_skb;
231
232#if 0
233 dev_fnstart(dev,
234 "(i1480u %p ptr %p size_left %zu)\n", i1480u, ptr, size_left);
235 dev_err(dev, "RX packet, %zu bytes\n", size_left);
236 dump_bytes(dev, ptr, size_left);
237#endif
238 i1480u_hdr_size = sizeof(struct wlp_rx_hdr);
239
240 while (size_left > 0) {
241 if (pkt_completed) {
242 i1480u_drop(i1480u, "RX: fragment follows completed"
243 "packet in same buffer. Dropping\n");
244 break;
245 }
246 untd_hdr = ptr;
247 if (size_left < sizeof(*untd_hdr)) {
248 i1480u_drop(i1480u, "RX: short UNTD header! Dropping\n");
249 goto out;
250 }
251 if (unlikely(untd_hdr_rx_tx(untd_hdr) == 0)) {
252 i1480u_drop(i1480u, "RX: TX bit set! Dropping\n");
253 goto out;
254 }
255 switch (untd_hdr_type(untd_hdr)) {
256 case i1480u_PKT_FRAG_1ST: {
257 struct untd_hdr_1st *untd_hdr_1st = (void *) untd_hdr;
258 dev_dbg(dev, "1st fragment\n");
259 untd_hdr_size = sizeof(struct untd_hdr_1st);
260 if (i1480u->rx_skb != NULL)
261 i1480u_fix(i1480u, "RX: 1st fragment out of "
262 "sequence! Fixing\n");
263 if (size_left < untd_hdr_size + i1480u_hdr_size) {
264 i1480u_drop(i1480u, "RX: short 1st fragment! "
265 "Dropping\n");
266 goto out;
267 }
268 i1480u->rx_untd_pkt_size = le16_to_cpu(untd_hdr->len)
269 - i1480u_hdr_size;
270 untd_frg_size = le16_to_cpu(untd_hdr_1st->fragment_len);
271 if (size_left < untd_hdr_size + untd_frg_size) {
272 i1480u_drop(i1480u,
273 "RX: short payload! Dropping\n");
274 goto out;
275 }
276 i1480u->rx_skb = skb;
277 i1480u_hdr = (void *) untd_hdr_1st + untd_hdr_size;
278 i1480u->rx_srcaddr = i1480u_hdr->srcaddr;
279 skb_put(i1480u->rx_skb, untd_hdr_size + untd_frg_size);
280 skb_pull(i1480u->rx_skb, untd_hdr_size + i1480u_hdr_size);
281 stats_add_sample(&i1480u->lqe_stats, (s8) i1480u_hdr->LQI - 7);
282 stats_add_sample(&i1480u->rssi_stats, i1480u_hdr->RSSI + 18);
283 rx_buf->data = NULL;
284 break;
285 }
286 case i1480u_PKT_FRAG_NXT: {
287 dev_dbg(dev, "nxt fragment\n");
288 untd_hdr_size = sizeof(struct untd_hdr_rst);
289 if (i1480u->rx_skb == NULL) {
290 i1480u_drop(i1480u, "RX: next fragment out of "
291 "sequence! Dropping\n");
292 goto out;
293 }
294 if (size_left < untd_hdr_size) {
295 i1480u_drop(i1480u, "RX: short NXT fragment! "
296 "Dropping\n");
297 goto out;
298 }
299 untd_frg_size = le16_to_cpu(untd_hdr->len);
300 if (size_left < untd_hdr_size + untd_frg_size) {
301 i1480u_drop(i1480u,
302 "RX: short payload! Dropping\n");
303 goto out;
304 }
305 memmove(skb_put(i1480u->rx_skb, untd_frg_size),
306 ptr + untd_hdr_size, untd_frg_size);
307 break;
308 }
309 case i1480u_PKT_FRAG_LST: {
310 dev_dbg(dev, "Lst fragment\n");
311 untd_hdr_size = sizeof(struct untd_hdr_rst);
312 if (i1480u->rx_skb == NULL) {
313 i1480u_drop(i1480u, "RX: last fragment out of "
314 "sequence! Dropping\n");
315 goto out;
316 }
317 if (size_left < untd_hdr_size) {
318 i1480u_drop(i1480u, "RX: short LST fragment! "
319 "Dropping\n");
320 goto out;
321 }
322 untd_frg_size = le16_to_cpu(untd_hdr->len);
323 if (size_left < untd_frg_size + untd_hdr_size) {
324 i1480u_drop(i1480u,
325 "RX: short payload! Dropping\n");
326 goto out;
327 }
328 memmove(skb_put(i1480u->rx_skb, untd_frg_size),
329 ptr + untd_hdr_size, untd_frg_size);
330 pkt_completed = 1;
331 break;
332 }
333 case i1480u_PKT_FRAG_CMP: {
334 dev_dbg(dev, "cmp fragment\n");
335 untd_hdr_size = sizeof(struct untd_hdr_cmp);
336 if (i1480u->rx_skb != NULL)
337 i1480u_fix(i1480u, "RX: fix out-of-sequence CMP"
338 " fragment!\n");
339 if (size_left < untd_hdr_size + i1480u_hdr_size) {
340 i1480u_drop(i1480u, "RX: short CMP fragment! "
341 "Dropping\n");
342 goto out;
343 }
344 i1480u->rx_untd_pkt_size = le16_to_cpu(untd_hdr->len);
345 untd_frg_size = i1480u->rx_untd_pkt_size;
346 if (size_left < i1480u->rx_untd_pkt_size + untd_hdr_size) {
347 i1480u_drop(i1480u,
348 "RX: short payload! Dropping\n");
349 goto out;
350 }
351 i1480u->rx_skb = skb;
352 i1480u_hdr = (void *) untd_hdr + untd_hdr_size;
353 i1480u->rx_srcaddr = i1480u_hdr->srcaddr;
354 stats_add_sample(&i1480u->lqe_stats, (s8) i1480u_hdr->LQI - 7);
355 stats_add_sample(&i1480u->rssi_stats, i1480u_hdr->RSSI + 18);
356 skb_put(i1480u->rx_skb, untd_hdr_size + i1480u->rx_untd_pkt_size);
357 skb_pull(i1480u->rx_skb, untd_hdr_size + i1480u_hdr_size);
358 rx_buf->data = NULL;
359 pkt_completed = 1;
360 i1480u->rx_untd_pkt_size -= i1480u_hdr_size;
361 break;
362 }
363 default:
364 i1480u_drop(i1480u, "RX: unknown packet type %u! "
365 "Dropping\n", untd_hdr_type(untd_hdr));
366 goto out;
367 }
368 size_left -= untd_hdr_size + untd_frg_size;
369 if (size_left > 0)
370 ptr += untd_hdr_size + untd_frg_size;
371 }
372 if (pkt_completed)
373 i1480u_skb_deliver(i1480u);
374out:
375
376 if (rx_buf->data == NULL) {
377
378 new_skb = dev_alloc_skb(i1480u_MAX_RX_PKT_SIZE);
379 if (!new_skb) {
380 if (printk_ratelimit())
381 dev_err(dev,
382 "RX: cannot allocate RX buffer\n");
383 } else {
384 new_skb->dev = net_dev;
385 new_skb->ip_summed = CHECKSUM_NONE;
386 skb_reserve(new_skb, 2);
387 rx_buf->data = new_skb;
388 }
389 }
390 return;
391}
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423void i1480u_rx_cb(struct urb *urb)
424{
425 int result;
426 int do_parse_buffer = 1;
427 struct i1480u_rx_buf *rx_buf = urb->context;
428 struct i1480u *i1480u = rx_buf->i1480u;
429 struct device *dev = &i1480u->usb_iface->dev;
430 unsigned long flags;
431 u8 rx_buf_idx = rx_buf - i1480u->rx_buf;
432
433 switch (urb->status) {
434 case 0:
435 break;
436 case -ECONNRESET:
437 case -ENOENT:
438 case -ESHUTDOWN:
439 dev_err(dev, "RX URB[%u]: goind down %d\n",
440 rx_buf_idx, urb->status);
441 goto error;
442 default:
443 dev_err(dev, "RX URB[%u]: unknown status %d\n",
444 rx_buf_idx, urb->status);
445 if (edc_inc(&i1480u->rx_errors, EDC_MAX_ERRORS,
446 EDC_ERROR_TIMEFRAME)) {
447 dev_err(dev, "RX: max acceptable errors exceeded,"
448 " resetting device.\n");
449 i1480u_rx_unlink_urbs(i1480u);
450 wlp_reset_all(&i1480u->wlp);
451 goto error;
452 }
453 do_parse_buffer = 0;
454 break;
455 }
456 spin_lock_irqsave(&i1480u->lock, flags);
457
458 if (do_parse_buffer) {
459 i1480u_rx_buffer(rx_buf);
460 if (rx_buf->data) {
461 rx_buf->urb->transfer_buffer = rx_buf->data->data;
462 result = usb_submit_urb(rx_buf->urb, GFP_ATOMIC);
463 if (result < 0) {
464 dev_err(dev, "RX URB[%u]: cannot submit %d\n",
465 rx_buf_idx, result);
466 }
467 }
468 }
469 spin_unlock_irqrestore(&i1480u->lock, flags);
470error:
471 return;
472}
473
474