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
68
69
70
71
72
73
74
75#include <linux/if_arp.h>
76#include <linux/netdevice.h>
77#include "i2400m.h"
78
79
80#define D_SUBMODULE netdev
81#include "debug-levels.h"
82
83enum {
84
85
86
87
88
89
90 I2400M_MAX_MTU = 1400,
91 I2400M_TX_TIMEOUT = HZ,
92 I2400M_TX_QLEN = 5,
93};
94
95
96static
97int i2400m_open(struct net_device *net_dev)
98{
99 int result;
100 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
101 struct device *dev = i2400m_dev(i2400m);
102
103 d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m);
104 if (i2400m->ready == 0) {
105 dev_err(dev, "Device is still initializing\n");
106 result = -EBUSY;
107 } else
108 result = 0;
109 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
110 net_dev, i2400m, result);
111 return result;
112}
113
114
115
116
117
118
119
120static
121int i2400m_stop(struct net_device *net_dev)
122{
123 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
124 struct device *dev = i2400m_dev(i2400m);
125
126 d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m);
127
128
129
130
131 if (cancel_work_sync(&i2400m->wake_tx_ws) == 0
132 && i2400m->wake_tx_skb != NULL) {
133 unsigned long flags;
134 struct sk_buff *wake_tx_skb;
135 spin_lock_irqsave(&i2400m->tx_lock, flags);
136 wake_tx_skb = i2400m->wake_tx_skb;
137 i2400m->wake_tx_skb = NULL;
138 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
139 i2400m_put(i2400m);
140 kfree_skb(wake_tx_skb);
141 }
142 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = 0\n", net_dev, i2400m);
143 return 0;
144}
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166void i2400m_wake_tx_work(struct work_struct *ws)
167{
168 int result;
169 struct i2400m *i2400m = container_of(ws, struct i2400m, wake_tx_ws);
170 struct device *dev = i2400m_dev(i2400m);
171 struct sk_buff *skb = i2400m->wake_tx_skb;
172 unsigned long flags;
173
174 spin_lock_irqsave(&i2400m->tx_lock, flags);
175 skb = i2400m->wake_tx_skb;
176 i2400m->wake_tx_skb = NULL;
177 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
178
179 d_fnstart(3, dev, "(ws %p i2400m %p skb %p)\n", ws, i2400m, skb);
180 result = -EINVAL;
181 if (skb == NULL) {
182 dev_err(dev, "WAKE&TX: skb dissapeared!\n");
183 goto out_put;
184 }
185 result = i2400m_cmd_exit_idle(i2400m);
186 if (result == -EILSEQ)
187 result = 0;
188 if (result < 0) {
189 dev_err(dev, "WAKE&TX: device didn't get out of idle: "
190 "%d\n", result);
191 goto error;
192 }
193 result = wait_event_timeout(i2400m->state_wq,
194 i2400m->state != I2400M_SS_IDLE, 5 * HZ);
195 if (result == 0)
196 result = -ETIMEDOUT;
197 if (result < 0) {
198 dev_err(dev, "WAKE&TX: error waiting for device to exit IDLE: "
199 "%d\n", result);
200 goto error;
201 }
202 msleep(20);
203 result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA);
204 netif_wake_queue(i2400m->wimax_dev.net_dev);
205error:
206 kfree_skb(skb);
207out_put:
208 i2400m_put(i2400m);
209 d_fnend(3, dev, "(ws %p i2400m %p skb %p) = void [%d]\n",
210 ws, i2400m, skb, result);
211}
212
213
214
215
216
217
218
219
220
221
222static
223void i2400m_tx_prep_header(struct sk_buff *skb)
224{
225 struct i2400m_pl_data_hdr *pl_hdr;
226 skb_pull(skb, ETH_HLEN);
227 pl_hdr = (struct i2400m_pl_data_hdr *) skb_push(skb, sizeof(*pl_hdr));
228 pl_hdr->reserved = 0;
229}
230
231
232
233
234
235
236
237
238
239
240
241
242
243static
244int i2400m_net_wake_tx(struct i2400m *i2400m, struct net_device *net_dev,
245 struct sk_buff *skb)
246{
247 int result;
248 struct device *dev = i2400m_dev(i2400m);
249 unsigned long flags;
250
251 d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
252 if (net_ratelimit()) {
253 d_printf(3, dev, "WAKE&NETTX: "
254 "skb %p sending %d bytes to radio\n",
255 skb, skb->len);
256 d_dump(4, dev, skb->data, skb->len);
257 }
258
259
260
261 result = 0;
262 spin_lock_irqsave(&i2400m->tx_lock, flags);
263 if (!work_pending(&i2400m->wake_tx_ws)) {
264 netif_stop_queue(net_dev);
265 i2400m_get(i2400m);
266 i2400m->wake_tx_skb = skb_get(skb);
267 i2400m_tx_prep_header(skb);
268 result = schedule_work(&i2400m->wake_tx_ws);
269 WARN_ON(result == 0);
270 }
271 spin_unlock_irqrestore(&i2400m->tx_lock, flags);
272 if (result == 0) {
273
274
275
276
277 if (net_ratelimit())
278 d_printf(1, dev, "NETTX: device exiting idle, "
279 "dropping skb %p, queue running %d\n",
280 skb, netif_queue_stopped(net_dev));
281 result = -EBUSY;
282 }
283 d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result);
284 return result;
285}
286
287
288
289
290
291
292
293
294
295
296static
297int i2400m_net_tx(struct i2400m *i2400m, struct net_device *net_dev,
298 struct sk_buff *skb)
299{
300 int result;
301 struct device *dev = i2400m_dev(i2400m);
302
303 d_fnstart(3, dev, "(i2400m %p net_dev %p skb %p)\n",
304 i2400m, net_dev, skb);
305
306 net_dev->trans_start = jiffies;
307 i2400m_tx_prep_header(skb);
308 d_printf(3, dev, "NETTX: skb %p sending %d bytes to radio\n",
309 skb, skb->len);
310 d_dump(4, dev, skb->data, skb->len);
311 result = i2400m_tx(i2400m, skb->data, skb->len, I2400M_PT_DATA);
312 d_fnend(3, dev, "(i2400m %p net_dev %p skb %p) = %d\n",
313 i2400m, net_dev, skb, result);
314 return result;
315}
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336static
337netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb,
338 struct net_device *net_dev)
339{
340 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
341 struct device *dev = i2400m_dev(i2400m);
342 int result;
343
344 d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
345 if (i2400m->state == I2400M_SS_IDLE)
346 result = i2400m_net_wake_tx(i2400m, net_dev, skb);
347 else
348 result = i2400m_net_tx(i2400m, net_dev, skb);
349 if (result < 0)
350 net_dev->stats.tx_dropped++;
351 else {
352 net_dev->stats.tx_packets++;
353 net_dev->stats.tx_bytes += skb->len;
354 }
355 kfree_skb(skb);
356
357 d_fnend(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
358 return NETDEV_TX_OK;
359}
360
361
362static
363int i2400m_change_mtu(struct net_device *net_dev, int new_mtu)
364{
365 int result;
366 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
367 struct device *dev = i2400m_dev(i2400m);
368
369 if (new_mtu >= I2400M_MAX_MTU) {
370 dev_err(dev, "Cannot change MTU to %d (max is %d)\n",
371 new_mtu, I2400M_MAX_MTU);
372 result = -EINVAL;
373 } else {
374 net_dev->mtu = new_mtu;
375 result = 0;
376 }
377 return result;
378}
379
380
381static
382void i2400m_tx_timeout(struct net_device *net_dev)
383{
384
385
386
387
388
389
390
391 net_dev->stats.tx_errors++;
392 return;
393}
394
395
396
397
398
399
400
401
402
403static
404void i2400m_rx_fake_eth_header(struct net_device *net_dev,
405 void *_eth_hdr, __be16 protocol)
406{
407 struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
408 struct ethhdr *eth_hdr = _eth_hdr;
409
410 memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
411 memcpy(eth_hdr->h_source, i2400m->src_mac_addr,
412 sizeof(eth_hdr->h_source));
413 eth_hdr->h_proto = protocol;
414}
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453void i2400m_net_rx(struct i2400m *i2400m, struct sk_buff *skb_rx,
454 unsigned i, const void *buf, int buf_len)
455{
456 struct net_device *net_dev = i2400m->wimax_dev.net_dev;
457 struct device *dev = i2400m_dev(i2400m);
458 struct sk_buff *skb;
459
460 d_fnstart(2, dev, "(i2400m %p buf %p buf_len %d)\n",
461 i2400m, buf, buf_len);
462 if (i) {
463 skb = skb_get(skb_rx);
464 d_printf(2, dev, "RX: reusing first payload skb %p\n", skb);
465 skb_pull(skb, buf - (void *) skb->data);
466 skb_trim(skb, (void *) skb_end_pointer(skb) - buf);
467 } else {
468
469
470 skb = __netdev_alloc_skb(net_dev, buf_len, GFP_KERNEL);
471 if (skb == NULL) {
472 dev_err(dev, "NETRX: no memory to realloc skb\n");
473 net_dev->stats.rx_dropped++;
474 goto error_skb_realloc;
475 }
476 memcpy(skb_put(skb, buf_len), buf, buf_len);
477 }
478 i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
479 skb->data - ETH_HLEN,
480 cpu_to_be16(ETH_P_IP));
481 skb_set_mac_header(skb, -ETH_HLEN);
482 skb->dev = i2400m->wimax_dev.net_dev;
483 skb->protocol = htons(ETH_P_IP);
484 net_dev->stats.rx_packets++;
485 net_dev->stats.rx_bytes += buf_len;
486 d_printf(3, dev, "NETRX: receiving %d bytes to network stack\n",
487 buf_len);
488 d_dump(4, dev, buf, buf_len);
489 netif_rx_ni(skb);
490error_skb_realloc:
491 d_fnend(2, dev, "(i2400m %p buf %p buf_len %d) = void\n",
492 i2400m, buf, buf_len);
493}
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518void i2400m_net_erx(struct i2400m *i2400m, struct sk_buff *skb,
519 enum i2400m_cs cs)
520{
521 struct net_device *net_dev = i2400m->wimax_dev.net_dev;
522 struct device *dev = i2400m_dev(i2400m);
523 int protocol;
524
525 d_fnstart(2, dev, "(i2400m %p skb %p [%u] cs %d)\n",
526 i2400m, skb, skb->len, cs);
527 switch(cs) {
528 case I2400M_CS_IPV4_0:
529 case I2400M_CS_IPV4:
530 protocol = ETH_P_IP;
531 i2400m_rx_fake_eth_header(i2400m->wimax_dev.net_dev,
532 skb->data - ETH_HLEN,
533 cpu_to_be16(ETH_P_IP));
534 skb_set_mac_header(skb, -ETH_HLEN);
535 skb->dev = i2400m->wimax_dev.net_dev;
536 skb->protocol = htons(ETH_P_IP);
537 net_dev->stats.rx_packets++;
538 net_dev->stats.rx_bytes += skb->len;
539 break;
540 default:
541 dev_err(dev, "ERX: BUG? CS type %u unsupported\n", cs);
542 goto error;
543
544 }
545 d_printf(3, dev, "ERX: receiving %d bytes to the network stack\n",
546 skb->len);
547 d_dump(4, dev, skb->data, skb->len);
548 netif_rx_ni(skb);
549error:
550 d_fnend(2, dev, "(i2400m %p skb %p [%u] cs %d) = void\n",
551 i2400m, skb, skb->len, cs);
552}
553
554static const struct net_device_ops i2400m_netdev_ops = {
555 .ndo_open = i2400m_open,
556 .ndo_stop = i2400m_stop,
557 .ndo_start_xmit = i2400m_hard_start_xmit,
558 .ndo_tx_timeout = i2400m_tx_timeout,
559 .ndo_change_mtu = i2400m_change_mtu,
560};
561
562
563
564
565
566
567
568void i2400m_netdev_setup(struct net_device *net_dev)
569{
570 d_fnstart(3, NULL, "(net_dev %p)\n", net_dev);
571 ether_setup(net_dev);
572 net_dev->mtu = I2400M_MAX_MTU;
573 net_dev->tx_queue_len = I2400M_TX_QLEN;
574 net_dev->features =
575 NETIF_F_VLAN_CHALLENGED
576 | NETIF_F_HIGHDMA;
577 net_dev->flags =
578 IFF_NOARP
579 & (~IFF_BROADCAST
580 & ~IFF_MULTICAST);
581 net_dev->watchdog_timeo = I2400M_TX_TIMEOUT;
582 net_dev->netdev_ops = &i2400m_netdev_ops;
583 d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev);
584}
585EXPORT_SYMBOL_GPL(i2400m_netdev_setup);
586
587