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#include <linux/module.h>
53#include <linux/kernel.h>
54#include <linux/sched.h>
55#include <linux/types.h>
56#include <linux/skbuff.h>
57#include <linux/slab.h>
58#include <linux/proc_fs.h>
59#include <linux/interrupt.h>
60#include <linux/netdevice.h>
61#include <linux/kmod.h>
62#include <linux/if_arp.h>
63#include <linux/wireless.h>
64#include <linux/sockios.h>
65#include <linux/etherdevice.h>
66#include <linux/if_ether.h>
67#include <linux/byteorder/generic.h>
68#include <linux/bitops.h>
69#include <linux/uaccess.h>
70#include <asm/byteorder.h>
71
72#ifdef SIOCETHTOOL
73#include <linux/ethtool.h>
74#endif
75
76#include <net/iw_handler.h>
77#include <net/net_namespace.h>
78
79#include "p80211types.h"
80#include "p80211hdr.h"
81#include "p80211conv.h"
82#include "p80211mgmt.h"
83#include "p80211msg.h"
84#include "p80211netdev.h"
85#include "p80211ioctl.h"
86#include "p80211req.h"
87#include "p80211metastruct.h"
88#include "p80211metadef.h"
89
90
91static void p80211netdev_rx_bh(unsigned long arg);
92
93
94static int p80211knetdev_init(netdevice_t *netdev);
95static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev);
96static int p80211knetdev_open(netdevice_t *netdev);
97static int p80211knetdev_stop(netdevice_t *netdev);
98static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
99 netdevice_t *netdev);
100static void p80211knetdev_set_multicast_list(netdevice_t *dev);
101static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr,
102 int cmd);
103static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
104static void p80211knetdev_tx_timeout(netdevice_t *netdev);
105static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc);
106
107int wlan_watchdog = 5000;
108module_param(wlan_watchdog, int, 0644);
109MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
110
111int wlan_wext_write = 1;
112module_param(wlan_wext_write, int, 0644);
113MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
114
115
116
117
118
119
120
121
122
123
124
125
126
127static int p80211knetdev_init(netdevice_t *netdev)
128{
129
130
131
132
133 return 0;
134}
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150static struct net_device_stats *p80211knetdev_get_stats(netdevice_t * netdev)
151{
152 wlandevice_t *wlandev = netdev->ml_priv;
153
154
155
156
157 return &(wlandev->linux_stats);
158}
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174static int p80211knetdev_open(netdevice_t *netdev)
175{
176 int result = 0;
177 wlandevice_t *wlandev = netdev->ml_priv;
178
179
180 if (wlandev->msdstate != WLAN_MSD_RUNNING)
181 return -ENODEV;
182
183
184 if (wlandev->open != NULL) {
185 result = wlandev->open(wlandev);
186 if (result == 0) {
187 netif_start_queue(wlandev->netdev);
188 wlandev->state = WLAN_DEVICE_OPEN;
189 }
190 } else {
191 result = -EAGAIN;
192 }
193
194 return result;
195}
196
197
198
199
200
201
202
203
204
205
206
207
208
209static int p80211knetdev_stop(netdevice_t *netdev)
210{
211 int result = 0;
212 wlandevice_t *wlandev = netdev->ml_priv;
213
214 if (wlandev->close != NULL)
215 result = wlandev->close(wlandev);
216
217 netif_stop_queue(wlandev->netdev);
218 wlandev->state = WLAN_DEVICE_CLOSED;
219
220 return result;
221}
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
237{
238
239 skb_queue_tail(&wlandev->nsd_rxq, skb);
240
241 tasklet_schedule(&wlandev->rx_bh);
242
243 return;
244}
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259static void p80211netdev_rx_bh(unsigned long arg)
260{
261 wlandevice_t *wlandev = (wlandevice_t *) arg;
262 struct sk_buff *skb = NULL;
263 netdevice_t *dev = wlandev->netdev;
264 p80211_hdr_a3_t *hdr;
265 u16 fc;
266
267
268 while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
269 if (wlandev->state == WLAN_DEVICE_OPEN) {
270
271 if (dev->type != ARPHRD_ETHER) {
272
273
274
275
276 skb->dev = dev;
277 skb_reset_mac_header(skb);
278 skb->ip_summed = CHECKSUM_NONE;
279 skb->pkt_type = PACKET_OTHERHOST;
280 skb->protocol = htons(ETH_P_80211_RAW);
281 dev->last_rx = jiffies;
282
283 wlandev->linux_stats.rx_packets++;
284 wlandev->linux_stats.rx_bytes += skb->len;
285 netif_rx_ni(skb);
286 continue;
287 } else {
288 hdr = (p80211_hdr_a3_t *) skb->data;
289 fc = le16_to_cpu(hdr->fc);
290 if (p80211_rx_typedrop(wlandev, fc)) {
291 dev_kfree_skb(skb);
292 continue;
293 }
294
295
296 if (wlandev->netdev->flags & IFF_ALLMULTI) {
297
298 if (memcmp
299 (hdr->a1, wlandev->netdev->dev_addr,
300 ETH_ALEN) != 0) {
301
302 if (!(hdr->a1[0] & 0x01)) {
303 dev_kfree_skb(skb);
304 continue;
305 }
306 }
307 }
308
309 if (skb_p80211_to_ether
310 (wlandev, wlandev->ethconv, skb) == 0) {
311 skb->dev->last_rx = jiffies;
312 wlandev->linux_stats.rx_packets++;
313 wlandev->linux_stats.rx_bytes +=
314 skb->len;
315 netif_rx_ni(skb);
316 continue;
317 }
318 pr_debug("p80211_to_ether failed.\n");
319 }
320 }
321 dev_kfree_skb(skb);
322 }
323}
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
345 netdevice_t *netdev)
346{
347 int result = 0;
348 int txresult = -1;
349 wlandevice_t *wlandev = netdev->ml_priv;
350 p80211_hdr_t p80211_hdr;
351 p80211_metawep_t p80211_wep;
352
353 if (skb == NULL)
354 return NETDEV_TX_OK;
355
356 if (wlandev->state != WLAN_DEVICE_OPEN) {
357 result = 1;
358 goto failed;
359 }
360
361 memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
362 memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
363
364 if (netif_queue_stopped(netdev)) {
365 pr_debug("called when queue stopped.\n");
366 result = 1;
367 goto failed;
368 }
369
370 netif_stop_queue(netdev);
371
372
373 switch (wlandev->macmode) {
374 case WLAN_MACMODE_IBSS_STA:
375 case WLAN_MACMODE_ESS_STA:
376 case WLAN_MACMODE_ESS_AP:
377 break;
378 default:
379
380
381
382
383 if (skb->protocol != ETH_P_80211_RAW) {
384 netif_start_queue(wlandev->netdev);
385 printk(KERN_NOTICE
386 "Tx attempt prior to association, frame dropped.\n");
387 wlandev->linux_stats.tx_dropped++;
388 result = 0;
389 goto failed;
390 }
391 break;
392 }
393
394
395 if (skb->protocol == ETH_P_80211_RAW) {
396 if (!capable(CAP_NET_ADMIN)) {
397 result = 1;
398 goto failed;
399 }
400
401 memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
402 skb_pull(skb, sizeof(p80211_hdr_t));
403 } else {
404 if (skb_ether_to_p80211
405 (wlandev, wlandev->ethconv, skb, &p80211_hdr,
406 &p80211_wep) != 0) {
407
408 pr_debug("ether_to_80211(%d) failed.\n",
409 wlandev->ethconv);
410 result = 1;
411 goto failed;
412 }
413 }
414 if (wlandev->txframe == NULL) {
415 result = 1;
416 goto failed;
417 }
418
419 netdev->trans_start = jiffies;
420
421 wlandev->linux_stats.tx_packets++;
422
423 wlandev->linux_stats.tx_bytes += skb->len;
424
425 txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
426
427 if (txresult == 0) {
428
429
430 netif_wake_queue(wlandev->netdev);
431 result = NETDEV_TX_OK;
432 } else if (txresult == 1) {
433
434 pr_debug("txframe success, no more bufs\n");
435
436
437 result = NETDEV_TX_OK;
438 } else if (txresult == 2) {
439
440 pr_debug("txframe returned alloc_fail\n");
441 result = NETDEV_TX_BUSY;
442 } else {
443
444 pr_debug("txframe returned full or busy\n");
445 result = NETDEV_TX_BUSY;
446 }
447
448failed:
449
450 if ((p80211_wep.data) && (p80211_wep.data != skb->data))
451 kzfree(p80211_wep.data);
452
453
454 if (!result)
455 dev_kfree_skb(skb);
456
457 return result;
458}
459
460
461
462
463
464
465
466
467
468
469
470
471
472static void p80211knetdev_set_multicast_list(netdevice_t *dev)
473{
474 wlandevice_t *wlandev = dev->ml_priv;
475
476
477
478 if (wlandev->set_multicast_list)
479 wlandev->set_multicast_list(wlandev, dev);
480
481}
482
483#ifdef SIOCETHTOOL
484
485static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
486{
487 u32 ethcmd;
488 struct ethtool_drvinfo info;
489 struct ethtool_value edata;
490
491 memset(&info, 0, sizeof(info));
492 memset(&edata, 0, sizeof(edata));
493
494 if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
495 return -EFAULT;
496
497 switch (ethcmd) {
498 case ETHTOOL_GDRVINFO:
499 info.cmd = ethcmd;
500 snprintf(info.driver, sizeof(info.driver), "p80211_%s",
501 wlandev->nsdname);
502 snprintf(info.version, sizeof(info.version), "%s",
503 WLAN_RELEASE);
504
505 if (copy_to_user(useraddr, &info, sizeof(info)))
506 return -EFAULT;
507 return 0;
508#ifdef ETHTOOL_GLINK
509 case ETHTOOL_GLINK:
510 edata.cmd = ethcmd;
511
512 if (wlandev->linkstatus &&
513 (wlandev->macmode != WLAN_MACMODE_NONE)) {
514 edata.data = 1;
515 } else {
516 edata.data = 0;
517 }
518
519 if (copy_to_user(useraddr, &edata, sizeof(edata)))
520 return -EFAULT;
521 return 0;
522 }
523#endif
524
525 return -EOPNOTSUPP;
526}
527
528#endif
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
558{
559 int result = 0;
560 p80211ioctl_req_t *req = (p80211ioctl_req_t *) ifr;
561 wlandevice_t *wlandev = dev->ml_priv;
562 u8 *msgbuf;
563
564 pr_debug("rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
565
566#ifdef SIOCETHTOOL
567 if (cmd == SIOCETHTOOL) {
568 result =
569 p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data);
570 goto bail;
571 }
572#endif
573
574
575 if (req->magic != P80211_IOCTL_MAGIC) {
576 result = -ENOSYS;
577 goto bail;
578 }
579
580 if (cmd == P80211_IFTEST) {
581 result = 0;
582 goto bail;
583 } else if (cmd != P80211_IFREQ) {
584 result = -ENOSYS;
585 goto bail;
586 }
587
588
589 if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) {
590 if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
591 result = -EFAULT;
592 else
593 result = p80211req_dorequest(wlandev, msgbuf);
594
595 if (result == 0) {
596 if (copy_to_user
597 ((void __user *)req->data, msgbuf, req->len)) {
598 result = -EFAULT;
599 }
600 }
601 kfree(msgbuf);
602 } else {
603 result = -ENOMEM;
604 }
605bail:
606 return result;
607}
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
635{
636 struct sockaddr *new_addr = addr;
637 p80211msg_dot11req_mibset_t dot11req;
638 p80211item_unk392_t *mibattr;
639 p80211item_pstr6_t *macaddr;
640 p80211item_uint32_t *resultcode;
641 int result = 0;
642
643
644 if (netif_running(dev))
645 return -EBUSY;
646
647
648 mibattr = &dot11req.mibattribute;
649 macaddr = (p80211item_pstr6_t *) & mibattr->data;
650 resultcode = &dot11req.resultcode;
651
652
653 memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t));
654 dot11req.msgcode = DIDmsg_dot11req_mibset;
655 dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
656 memcpy(dot11req.devname,
657 ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
658
659
660 mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
661 mibattr->status = P80211ENUM_msgitem_status_data_ok;
662 mibattr->len = sizeof(mibattr->data);
663
664 macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
665 macaddr->status = P80211ENUM_msgitem_status_data_ok;
666 macaddr->len = sizeof(macaddr->data);
667 macaddr->data.len = ETH_ALEN;
668 memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
669
670
671 resultcode->did = DIDmsg_dot11req_mibset_resultcode;
672 resultcode->status = P80211ENUM_msgitem_status_no_value;
673 resultcode->len = sizeof(resultcode->data);
674 resultcode->data = 0;
675
676
677 result = p80211req_dorequest(dev->ml_priv, (u8 *) & dot11req);
678
679
680
681
682 if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
683 printk(KERN_ERR
684 "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
685 result = -EADDRNOTAVAIL;
686 } else {
687
688 memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
689 }
690
691 return result;
692}
693
694static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
695{
696
697
698 if ((new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
699 return -EINVAL;
700
701 dev->mtu = new_mtu;
702
703 return 0;
704}
705
706static const struct net_device_ops p80211_netdev_ops = {
707 .ndo_init = p80211knetdev_init,
708 .ndo_open = p80211knetdev_open,
709 .ndo_stop = p80211knetdev_stop,
710 .ndo_get_stats = p80211knetdev_get_stats,
711 .ndo_start_xmit = p80211knetdev_hard_start_xmit,
712 .ndo_set_multicast_list = p80211knetdev_set_multicast_list,
713 .ndo_do_ioctl = p80211knetdev_do_ioctl,
714 .ndo_set_mac_address = p80211knetdev_set_mac_address,
715 .ndo_tx_timeout = p80211knetdev_tx_timeout,
716 .ndo_change_mtu = wlan_change_mtu,
717 .ndo_validate_addr = eth_validate_addr,
718};
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742int wlan_setup(wlandevice_t *wlandev)
743{
744 int result = 0;
745 netdevice_t *dev;
746
747
748 wlandev->state = WLAN_DEVICE_CLOSED;
749 wlandev->ethconv = WLAN_ETHCONV_8021h;
750 wlandev->macmode = WLAN_MACMODE_NONE;
751
752
753 skb_queue_head_init(&wlandev->nsd_rxq);
754 tasklet_init(&wlandev->rx_bh,
755 p80211netdev_rx_bh, (unsigned long)wlandev);
756
757
758 dev = alloc_netdev(0, "wlan%d", ether_setup);
759 if (dev == NULL) {
760 printk(KERN_ERR "Failed to alloc netdev.\n");
761 result = 1;
762 } else {
763 wlandev->netdev = dev;
764 dev->ml_priv = wlandev;
765 dev->netdev_ops = &p80211_netdev_ops;
766
767 dev->wireless_handlers = &p80211wext_handler_def;
768
769 netif_stop_queue(dev);
770 netif_carrier_off(dev);
771 }
772
773 return result;
774}
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797int wlan_unsetup(wlandevice_t *wlandev)
798{
799 int result = 0;
800
801 tasklet_kill(&wlandev->rx_bh);
802
803 if (wlandev->netdev == NULL) {
804 printk(KERN_ERR "called without wlandev->netdev set.\n");
805 result = 1;
806 } else {
807 free_netdev(wlandev->netdev);
808 wlandev->netdev = NULL;
809 }
810
811 return 0;
812}
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833int register_wlandev(wlandevice_t *wlandev)
834{
835 int i = 0;
836
837 i = register_netdev(wlandev->netdev);
838 if (i)
839 return i;
840
841 return 0;
842}
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861int unregister_wlandev(wlandevice_t *wlandev)
862{
863 struct sk_buff *skb;
864
865 unregister_netdev(wlandev->netdev);
866
867
868 while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
869 dev_kfree_skb(skb);
870
871 return 0;
872}
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904void p80211netdev_hwremoved(wlandevice_t *wlandev)
905{
906 wlandev->hwremoved = 1;
907 if (wlandev->state == WLAN_DEVICE_OPEN)
908 netif_stop_queue(wlandev->netdev);
909
910 netif_device_detach(wlandev->netdev);
911}
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc)
935{
936 u16 ftype;
937 u16 fstype;
938 int drop = 0;
939
940 ftype = WLAN_GET_FC_FTYPE(fc);
941 fstype = WLAN_GET_FC_FSTYPE(fc);
942#if 0
943 pr_debug("rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
944#endif
945 switch (ftype) {
946 case WLAN_FTYPE_MGMT:
947 if ((wlandev->netdev->flags & IFF_PROMISC) ||
948 (wlandev->netdev->flags & IFF_ALLMULTI)) {
949 drop = 1;
950 break;
951 }
952 pr_debug("rx'd mgmt:\n");
953 wlandev->rx.mgmt++;
954 switch (fstype) {
955 case WLAN_FSTYPE_ASSOCREQ:
956
957 wlandev->rx.assocreq++;
958 break;
959 case WLAN_FSTYPE_ASSOCRESP:
960
961 wlandev->rx.assocresp++;
962 break;
963 case WLAN_FSTYPE_REASSOCREQ:
964
965 wlandev->rx.reassocreq++;
966 break;
967 case WLAN_FSTYPE_REASSOCRESP:
968
969 wlandev->rx.reassocresp++;
970 break;
971 case WLAN_FSTYPE_PROBEREQ:
972
973 wlandev->rx.probereq++;
974 break;
975 case WLAN_FSTYPE_PROBERESP:
976
977 wlandev->rx.proberesp++;
978 break;
979 case WLAN_FSTYPE_BEACON:
980
981 wlandev->rx.beacon++;
982 break;
983 case WLAN_FSTYPE_ATIM:
984
985 wlandev->rx.atim++;
986 break;
987 case WLAN_FSTYPE_DISASSOC:
988
989 wlandev->rx.disassoc++;
990 break;
991 case WLAN_FSTYPE_AUTHEN:
992
993 wlandev->rx.authen++;
994 break;
995 case WLAN_FSTYPE_DEAUTHEN:
996
997 wlandev->rx.deauthen++;
998 break;
999 default:
1000
1001 wlandev->rx.mgmt_unknown++;
1002 break;
1003 }
1004
1005 drop = 2;
1006 break;
1007
1008 case WLAN_FTYPE_CTL:
1009 if ((wlandev->netdev->flags & IFF_PROMISC) ||
1010 (wlandev->netdev->flags & IFF_ALLMULTI)) {
1011 drop = 1;
1012 break;
1013 }
1014 pr_debug("rx'd ctl:\n");
1015 wlandev->rx.ctl++;
1016 switch (fstype) {
1017 case WLAN_FSTYPE_PSPOLL:
1018
1019 wlandev->rx.pspoll++;
1020 break;
1021 case WLAN_FSTYPE_RTS:
1022
1023 wlandev->rx.rts++;
1024 break;
1025 case WLAN_FSTYPE_CTS:
1026
1027 wlandev->rx.cts++;
1028 break;
1029 case WLAN_FSTYPE_ACK:
1030
1031 wlandev->rx.ack++;
1032 break;
1033 case WLAN_FSTYPE_CFEND:
1034
1035 wlandev->rx.cfend++;
1036 break;
1037 case WLAN_FSTYPE_CFENDCFACK:
1038
1039 wlandev->rx.cfendcfack++;
1040 break;
1041 default:
1042
1043 wlandev->rx.ctl_unknown++;
1044 break;
1045 }
1046
1047 drop = 2;
1048 break;
1049
1050 case WLAN_FTYPE_DATA:
1051 wlandev->rx.data++;
1052 switch (fstype) {
1053 case WLAN_FSTYPE_DATAONLY:
1054 wlandev->rx.dataonly++;
1055 break;
1056 case WLAN_FSTYPE_DATA_CFACK:
1057 wlandev->rx.data_cfack++;
1058 break;
1059 case WLAN_FSTYPE_DATA_CFPOLL:
1060 wlandev->rx.data_cfpoll++;
1061 break;
1062 case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
1063 wlandev->rx.data__cfack_cfpoll++;
1064 break;
1065 case WLAN_FSTYPE_NULL:
1066 pr_debug("rx'd data:null\n");
1067 wlandev->rx.null++;
1068 break;
1069 case WLAN_FSTYPE_CFACK:
1070 pr_debug("rx'd data:cfack\n");
1071 wlandev->rx.cfack++;
1072 break;
1073 case WLAN_FSTYPE_CFPOLL:
1074 pr_debug("rx'd data:cfpoll\n");
1075 wlandev->rx.cfpoll++;
1076 break;
1077 case WLAN_FSTYPE_CFACK_CFPOLL:
1078 pr_debug("rx'd data:cfack_cfpoll\n");
1079 wlandev->rx.cfack_cfpoll++;
1080 break;
1081 default:
1082
1083 wlandev->rx.data_unknown++;
1084 break;
1085 }
1086
1087 break;
1088 }
1089 return drop;
1090}
1091
1092static void p80211knetdev_tx_timeout(netdevice_t *netdev)
1093{
1094 wlandevice_t *wlandev = netdev->ml_priv;
1095
1096 if (wlandev->tx_timeout) {
1097 wlandev->tx_timeout(wlandev);
1098 } else {
1099 printk(KERN_WARNING "Implement tx_timeout for %s\n",
1100 wlandev->nsdname);
1101 netif_wake_queue(wlandev->netdev);
1102 }
1103}
1104