Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / rt2860 / rt_main_dev.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27     Module Name:
28     rt_main_dev.c
29
30     Abstract:
31     Create and register network interface.
32
33     Revision History:
34     Who                 When            What
35     Justin P. Mattock   11/07/2010      Fix typos in comments
36     --------    ----------      ----------------------------------------------
37 */
38
39 #include "rt_config.h"
40
41 /*---------------------------------------------------------------------*/
42 /* Private Variables Used                                              */
43 /*---------------------------------------------------------------------*/
44
45 char *mac = "";         /* default 00:00:00:00:00:00 */
46 char *hostname = "";            /* default CMPC */
47 module_param(mac, charp, 0);
48 MODULE_PARM_DESC(mac, "rt28xx: wireless mac addr");
49
50 /*---------------------------------------------------------------------*/
51 /* Prototypes of Functions Used                                        */
52 /*---------------------------------------------------------------------*/
53
54 /* public function prototype */
55 int rt28xx_close(IN struct net_device *net_dev);
56 int rt28xx_open(struct net_device *net_dev);
57
58 /* private function prototype */
59 static int rt28xx_send_packets(IN struct sk_buff *skb_p,
60                                IN struct net_device *net_dev);
61
62 static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
63                                                        *net_dev);
64
65 /*
66 ========================================================================
67 Routine Description:
68     Close raxx interface.
69
70 Arguments:
71         *net_dev                        the raxx interface pointer
72
73 Return Value:
74     0                                   Open OK
75         otherwise                       Open Fail
76
77 Note:
78         1. if open fail, kernel will not call the close function.
79         2. Free memory for
80                 (1) Mlme Memory Handler:                MlmeHalt()
81                 (2) TX & RX:                                    RTMPFreeTxRxRingMemory()
82                 (3) BA Reordering:                              ba_reordering_resource_release()
83 ========================================================================
84 */
85 int MainVirtualIF_close(IN struct net_device *net_dev)
86 {
87         struct rt_rtmp_adapter *pAd = NULL;
88
89         GET_PAD_FROM_NET_DEV(pAd, net_dev);
90
91         /* Sanity check for pAd */
92         if (pAd == NULL)
93                 return 0;       /* close ok */
94
95         netif_carrier_off(pAd->net_dev);
96         netif_stop_queue(pAd->net_dev);
97
98         {
99                 BOOLEAN Cancelled;
100
101                 if (INFRA_ON(pAd) &&
102                     (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
103                         struct rt_mlme_disassoc_req DisReq;
104                         struct rt_mlme_queue_elem *MsgElem =
105                                 kmalloc(sizeof(struct rt_mlme_queue_elem),
106                                         MEM_ALLOC_FLAG);
107
108                         if (MsgElem) {
109                                 COPY_MAC_ADDR(DisReq.Addr,
110                                               pAd->CommonCfg.Bssid);
111                                 DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
112
113                                 MsgElem->Machine = ASSOC_STATE_MACHINE;
114                                 MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
115                                 MsgElem->MsgLen =
116                                     sizeof(struct rt_mlme_disassoc_req);
117                                 NdisMoveMemory(MsgElem->Msg, &DisReq,
118                                                sizeof
119                                                (struct rt_mlme_disassoc_req));
120
121                                 /* Prevent to connect AP again in STAMlmePeriodicExec */
122                                 pAd->MlmeAux.AutoReconnectSsidLen = 32;
123                                 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
124                                                pAd->MlmeAux.
125                                                AutoReconnectSsidLen);
126
127                                 pAd->Mlme.CntlMachine.CurrState =
128                                     CNTL_WAIT_OID_DISASSOC;
129                                 MlmeDisassocReqAction(pAd, MsgElem);
130                                 kfree(MsgElem);
131                         }
132
133                         RTMPusecDelay(1000);
134                 }
135
136                 RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer,
137                                 &Cancelled);
138                 RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
139                                 &Cancelled);
140         }
141
142         VIRTUAL_IF_DOWN(pAd);
143
144         RT_MOD_DEC_USE_COUNT();
145
146         return 0;               /* close ok */
147 }
148
149 /*
150 ========================================================================
151 Routine Description:
152     Open raxx interface.
153
154 Arguments:
155         *net_dev                        the raxx interface pointer
156
157 Return Value:
158     0                                   Open OK
159         otherwise                       Open Fail
160
161 Note:
162         1. if open fail, kernel will not call the close function.
163         2. Free memory for
164                 (1) Mlme Memory Handler:                MlmeHalt()
165                 (2) TX & RX:                                    RTMPFreeTxRxRingMemory()
166                 (3) BA Reordering:                              ba_reordering_resource_release()
167 ========================================================================
168 */
169 int MainVirtualIF_open(IN struct net_device *net_dev)
170 {
171         struct rt_rtmp_adapter *pAd = NULL;
172
173         GET_PAD_FROM_NET_DEV(pAd, net_dev);
174
175         /* Sanity check for pAd */
176         if (pAd == NULL)
177                 return 0;       /* close ok */
178
179         if (VIRTUAL_IF_UP(pAd) != 0)
180                 return -1;
181
182         /* increase MODULE use count */
183         RT_MOD_INC_USE_COUNT();
184
185         netif_start_queue(net_dev);
186         netif_carrier_on(net_dev);
187         netif_wake_queue(net_dev);
188
189         return 0;
190 }
191
192 /*
193 ========================================================================
194 Routine Description:
195     Close raxx interface.
196
197 Arguments:
198         *net_dev                        the raxx interface pointer
199
200 Return Value:
201     0                                   Open OK
202         otherwise                       Open Fail
203
204 Note:
205         1. if open fail, kernel will not call the close function.
206         2. Free memory for
207                 (1) Mlme Memory Handler:                MlmeHalt()
208                 (2) TX & RX:                                    RTMPFreeTxRxRingMemory()
209                 (3) BA Reordering:                              ba_reordering_resource_release()
210 ========================================================================
211 */
212 int rt28xx_close(struct net_device *dev)
213 {
214         struct net_device *net_dev = (struct net_device *)dev;
215         struct rt_rtmp_adapter *pAd = NULL;
216         BOOLEAN Cancelled;
217         u32 i = 0;
218
219 #ifdef RTMP_MAC_USB
220         DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
221         DECLARE_WAITQUEUE(wait, current);
222 #endif /* RTMP_MAC_USB // */
223
224         GET_PAD_FROM_NET_DEV(pAd, net_dev);
225
226         DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
227
228         Cancelled = FALSE;
229         /* Sanity check for pAd */
230         if (pAd == NULL)
231                 return 0;       /* close ok */
232
233         {
234 #ifdef RTMP_MAC_PCI
235                 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
236 #endif /* RTMP_MAC_PCI // */
237
238                 /* If driver doesn't wake up firmware here, */
239                 /* NICLoadFirmware will hang forever when interface is up again. */
240                 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
241                         AsicForceWakeup(pAd, TRUE);
242                 }
243 #ifdef RTMP_MAC_USB
244                 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
245 #endif /* RTMP_MAC_USB // */
246
247                 MlmeRadioOff(pAd);
248 #ifdef RTMP_MAC_PCI
249                 pAd->bPCIclkOff = FALSE;
250 #endif /* RTMP_MAC_PCI // */
251         }
252
253         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
254
255         for (i = 0; i < NUM_OF_TX_RING; i++) {
256                 while (pAd->DeQueueRunning[i] == TRUE) {
257                         DBGPRINT(RT_DEBUG_TRACE,
258                                  ("Waiting for TxQueue[%d] done..........\n",
259                                   i));
260                         RTMPusecDelay(1000);
261                 }
262         }
263
264 #ifdef RTMP_MAC_USB
265         /* ensure there are no more active urbs. */
266         add_wait_queue(&unlink_wakeup, &wait);
267         pAd->wait = &unlink_wakeup;
268
269         /* maybe wait for deletions to finish. */
270         i = 0;
271         /*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
272         while (i < 25) {
273                 unsigned long IrqFlags;
274
275                 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
276                 if (pAd->PendingRx == 0) {
277                         RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
278                         break;
279                 }
280                 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
281
282                 msleep(UNLINK_TIMEOUT_MS);      /*Time in millisecond */
283                 i++;
284         }
285         pAd->wait = NULL;
286         remove_wait_queue(&unlink_wakeup, &wait);
287 #endif /* RTMP_MAC_USB // */
288
289         /* Stop Mlme state machine */
290         MlmeHalt(pAd);
291
292         /* Close net tasklets */
293         RtmpNetTaskExit(pAd);
294
295         {
296                 MacTableReset(pAd);
297         }
298
299         MeasureReqTabExit(pAd);
300         TpcReqTabExit(pAd);
301
302         /* Close kernel threads */
303         RtmpMgmtTaskExit(pAd);
304
305 #ifdef RTMP_MAC_PCI
306         {
307                 BOOLEAN brc;
308                 /*      unsigned long                   Value; */
309
310                 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
311                         RTMP_ASIC_INTERRUPT_DISABLE(pAd);
312                 }
313                 /* Receive packets to clear DMA index after disable interrupt. */
314                 /* RTMPHandleRxDoneInterrupt(pAd); */
315                 /* put radio off to save power when driver unloads.  After radiooff, can't write/read register, so need to finish all. */
316                 /* register access before Radio off. */
317
318                 brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
319
320 /*In  solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */
321                 pAd->bPCIclkOff = FALSE;
322
323                 if (brc == FALSE) {
324                         DBGPRINT(RT_DEBUG_ERROR,
325                                  ("%s call RT28xxPciAsicRadioOff fail!\n",
326                                   __func__));
327                 }
328         }
329
330 /*
331         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
332         {
333                 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
334         }
335
336         // Disable Rx, register value supposed will remain after reset
337         NICIssueReset(pAd);
338 */
339 #endif /* RTMP_MAC_PCI // */
340
341         /* Free IRQ */
342         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
343 #ifdef RTMP_MAC_PCI
344                 /* Deregister interrupt function */
345                 RtmpOSIRQRelease(net_dev);
346 #endif /* RTMP_MAC_PCI // */
347                 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
348         }
349         /* Free Ring or USB buffers */
350         RTMPFreeTxRxRingMemory(pAd);
351
352         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
353
354         /* Free BA reorder resource */
355         ba_reordering_resource_release(pAd);
356
357         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
358
359 /*+++Modify by woody to solve the bulk fail+++*/
360         {
361         }
362
363         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
364         return 0;               /* close ok */
365 }                               /* End of rt28xx_close */
366
367 /*
368 ========================================================================
369 Routine Description:
370     Open raxx interface.
371
372 Arguments:
373         *net_dev                        the raxx interface pointer
374
375 Return Value:
376     0                                   Open OK
377         otherwise                       Open Fail
378
379 Note:
380 ========================================================================
381 */
382 int rt28xx_open(struct net_device *dev)
383 {
384         struct net_device *net_dev = (struct net_device *)dev;
385         struct rt_rtmp_adapter *pAd = NULL;
386         int retval = 0;
387         /*struct os_cookie *pObj; */
388
389         GET_PAD_FROM_NET_DEV(pAd, net_dev);
390
391         /* Sanity check for pAd */
392         if (pAd == NULL) {
393                 /* if 1st open fail, pAd will be free;
394                    So the net_dev->ml_priv will be NULL in 2rd open */
395                 return -1;
396         }
397
398         if (net_dev->priv_flags == INT_MAIN) {
399                 if (pAd->OpMode == OPMODE_STA)
400                         net_dev->wireless_handlers =
401                             (struct iw_handler_def *)&rt28xx_iw_handler_def;
402         }
403         /* Request interrupt service routine for PCI device */
404         /* register the interrupt routine with the os */
405         RtmpOSIRQRequest(net_dev);
406
407         /* Init IRQ parameters stored in pAd */
408         RTMP_IRQ_INIT(pAd);
409
410         /* Chip & other init */
411         if (rt28xx_init(pAd, mac, hostname) == FALSE)
412                 goto err;
413
414         /* Enable Interrupt */
415         RTMP_IRQ_ENABLE(pAd);
416
417         /* Now Enable RxTx */
418         RTMPEnableRxTx(pAd);
419         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
420
421         {
422                 u32 reg = 0;
423                 RTMP_IO_READ32(pAd, 0x1300, &reg);      /* clear garbage interrupts */
424                 printk(KERN_DEBUG "0x1300 = %08x\n", reg);
425         }
426
427         {
428 /*      u32 reg; */
429 /*      u8  byte; */
430 /*      u16 tmp; */
431
432 /*      RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg); */
433
434 /*      tmp = 0x0805; */
435 /*      reg  = (reg & 0xffff0000) | tmp; */
436 /*      RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
437
438         }
439 #ifdef RTMP_MAC_PCI
440         RTMPInitPCIeLinkCtrlValue(pAd);
441 #endif /* RTMP_MAC_PCI // */
442
443         return retval;
444
445 err:
446 /*+++Add by shiang, move from rt28xx_init() to here. */
447         RtmpOSIRQRelease(net_dev);
448 /*---Add by shiang, move from rt28xx_init() to here. */
449         return -1;
450 }                               /* End of rt28xx_open */
451
452 static const struct net_device_ops rt2860_netdev_ops = {
453         .ndo_open = MainVirtualIF_open,
454         .ndo_stop = MainVirtualIF_close,
455         .ndo_do_ioctl = rt28xx_sta_ioctl,
456         .ndo_get_stats = RT28xx_get_ether_stats,
457         .ndo_validate_addr = NULL,
458         .ndo_set_mac_address = eth_mac_addr,
459         .ndo_change_mtu = eth_change_mtu,
460         .ndo_start_xmit = rt28xx_send_packets,
461 };
462
463 struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
464                            struct rt_rtmp_os_netdev_op_hook *pNetDevHook)
465 {
466         struct net_device *net_dev = NULL;
467 /*      int             Status; */
468
469         net_dev =
470             RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(struct rt_rtmp_adapter *),
471                                INF_MAIN_DEV_NAME);
472         if (net_dev == NULL) {
473                 printk
474                     ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
475                 return NULL;
476         }
477
478         NdisZeroMemory((unsigned char *)pNetDevHook,
479                        sizeof(struct rt_rtmp_os_netdev_op_hook));
480         pNetDevHook->netdev_ops = &rt2860_netdev_ops;
481         pNetDevHook->priv_flags = INT_MAIN;
482         pNetDevHook->needProtcted = FALSE;
483
484         net_dev->ml_priv = (void *)pAd;
485         pAd->net_dev = net_dev;
486
487         netif_stop_queue(net_dev);
488
489         return net_dev;
490
491 }
492
493 /*
494 ========================================================================
495 Routine Description:
496     The entry point for Linux kernel sent packet to our driver.
497
498 Arguments:
499     sk_buff *skb                the pointer refer to a sk_buffer.
500
501 Return Value:
502     0
503
504 Note:
505         This function is the entry point of Tx Path for Os delivery packet to
506         our driver. You only can put OS-depened & STA/AP common handle procedures
507         in here.
508 ========================================================================
509 */
510 int rt28xx_packet_xmit(struct sk_buff *skb)
511 {
512         struct net_device *net_dev = skb->dev;
513         struct rt_rtmp_adapter *pAd = NULL;
514         int status = NETDEV_TX_OK;
515         void *pPacket = (void *)skb;
516
517         GET_PAD_FROM_NET_DEV(pAd, net_dev);
518
519         /* RT2870STA does this in RTMPSendPackets() */
520
521         {
522                 /* Drop send request since we are in monitor mode */
523                 if (MONITOR_ON(pAd)) {
524                         RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
525                         goto done;
526                 }
527         }
528
529         /* EapolStart size is 18 */
530         if (skb->len < 14) {
531                 /*printk("bad packet size: %d\n", pkt->len); */
532                 hex_dump("bad packet", skb->data, skb->len);
533                 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
534                 goto done;
535         }
536
537         RTMP_SET_PACKET_5VT(pPacket, 0);
538         STASendPackets((void *)pAd, (void **)&pPacket, 1);
539
540         status = NETDEV_TX_OK;
541 done:
542
543         return status;
544 }
545
546 /*
547 ========================================================================
548 Routine Description:
549     Send a packet to WLAN.
550
551 Arguments:
552     skb_p           points to our adapter
553     dev_p           which WLAN network interface
554
555 Return Value:
556     0: transmit successfully
557     otherwise: transmit fail
558
559 Note:
560 ========================================================================
561 */
562 static int rt28xx_send_packets(IN struct sk_buff *skb_p,
563                                IN struct net_device *net_dev)
564 {
565         struct rt_rtmp_adapter *pAd = NULL;
566
567         GET_PAD_FROM_NET_DEV(pAd, net_dev);
568
569         if (!(net_dev->flags & IFF_UP)) {
570                 RELEASE_NDIS_PACKET(pAd, (void *)skb_p,
571                                     NDIS_STATUS_FAILURE);
572                 return NETDEV_TX_OK;
573         }
574
575         NdisZeroMemory((u8 *)&skb_p->cb[CB_OFF], 15);
576         RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
577
578         return rt28xx_packet_xmit(skb_p);
579 }
580
581 /* This function will be called when query /proc */
582 struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev)
583 {
584         struct rt_rtmp_adapter *pAd = NULL;
585
586         GET_PAD_FROM_NET_DEV(pAd, net_dev);
587
588         DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
589
590         pAd->iw_stats.status = 0;       /* Status - device dependent for now */
591
592         /* link quality */
593         if (pAd->OpMode == OPMODE_STA)
594                 pAd->iw_stats.qual.qual =
595                     ((pAd->Mlme.ChannelQuality * 12) / 10 + 10);
596
597         if (pAd->iw_stats.qual.qual > 100)
598                 pAd->iw_stats.qual.qual = 100;
599
600         if (pAd->OpMode == OPMODE_STA) {
601                 pAd->iw_stats.qual.level =
602                     RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
603                                 pAd->StaCfg.RssiSample.LastRssi1,
604                                 pAd->StaCfg.RssiSample.LastRssi2);
605         }
606
607         pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66];      /* noise level (dBm) */
608
609         pAd->iw_stats.qual.noise += 256 - 143;
610         pAd->iw_stats.qual.updated = 1; /* Flags to know if updated */
611 #ifdef IW_QUAL_DBM
612         pAd->iw_stats.qual.updated |= IW_QUAL_DBM;      /* Level + Noise are dBm */
613 #endif /* IW_QUAL_DBM // */
614
615         pAd->iw_stats.discard.nwid = 0; /* Rx : Wrong nwid/essid */
616         pAd->iw_stats.miss.beacon = 0;  /* Missed beacons/superframe */
617
618         DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
619         return &pAd->iw_stats;
620 }
621
622 void tbtt_tasklet(unsigned long data)
623 {
624 /*#define MAX_TX_IN_TBTT                (16) */
625
626 }
627
628 /*
629     ========================================================================
630
631     Routine Description:
632         return ethernet statistics counter
633
634     Arguments:
635         net_dev                         Pointer to net_device
636
637     Return Value:
638         net_device_stats*
639
640     Note:
641
642     ========================================================================
643 */
644 static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
645                                                        *net_dev)
646 {
647         struct rt_rtmp_adapter *pAd = NULL;
648
649         if (net_dev)
650                 GET_PAD_FROM_NET_DEV(pAd, net_dev);
651
652         if (pAd) {
653
654                 pAd->stats.rx_packets =
655                     pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
656                 pAd->stats.tx_packets =
657                     pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
658
659                 pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
660                 pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
661
662                 pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
663                 pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
664
665                 pAd->stats.rx_dropped = 0;
666                 pAd->stats.tx_dropped = 0;
667
668                 pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;  /* multicast packets received */
669                 pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;      /* Collision packets */
670
671                 pAd->stats.rx_length_errors = 0;
672                 pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;       /* receiver ring buff overflow */
673                 pAd->stats.rx_crc_errors = 0;   /*pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error */
674                 pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;      /* recv'd frame alignment error */
675                 pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;       /* recv'r fifo overrun */
676                 pAd->stats.rx_missed_errors = 0;        /* receiver missed packet */
677
678                 /* detailed tx_errors */
679                 pAd->stats.tx_aborted_errors = 0;
680                 pAd->stats.tx_carrier_errors = 0;
681                 pAd->stats.tx_fifo_errors = 0;
682                 pAd->stats.tx_heartbeat_errors = 0;
683                 pAd->stats.tx_window_errors = 0;
684
685                 /* for cslip etc */
686                 pAd->stats.rx_compressed = 0;
687                 pAd->stats.tx_compressed = 0;
688
689                 return &pAd->stats;
690         } else
691                 return NULL;
692 }
693
694 BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
695 {
696
697         /* Unregister network device */
698         if (net_dev != NULL) {
699                 printk
700                     ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
701                      net_dev->name);
702                 RtmpOSNetDevDetach(net_dev);
703         }
704
705         return TRUE;
706
707 }
708
709 /*
710 ========================================================================
711 Routine Description:
712     Allocate memory for adapter control block.
713
714 Arguments:
715     pAd                                 Pointer to our adapter
716
717 Return Value:
718         NDIS_STATUS_SUCCESS
719         NDIS_STATUS_FAILURE
720         NDIS_STATUS_RESOURCES
721
722 Note:
723 ========================================================================
724 */
725 int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
726 {
727
728         *ppAd = vmalloc(sizeof(struct rt_rtmp_adapter));
729         /* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
730
731         if (*ppAd) {
732                 NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter));
733                 ((struct rt_rtmp_adapter *)*ppAd)->OS_Cookie = handle;
734                 return NDIS_STATUS_SUCCESS;
735         } else {
736                 return NDIS_STATUS_FAILURE;
737         }
738 }