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