linux/drivers/staging/rt2860/rt_main_dev.c
<<
>>
Prefs
   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
  45char *mac = "";         /* default 00:00:00:00:00:00 */
  46char *hostname = "";            /* default CMPC */
  47module_param(mac, charp, 0);
  48MODULE_PARM_DESC(mac, "rt28xx: wireless mac addr");
  49
  50/*---------------------------------------------------------------------*/
  51/* Prototypes of Functions Used                                        */
  52/*---------------------------------------------------------------------*/
  53
  54/* public function prototype */
  55int rt28xx_close(IN struct net_device *net_dev);
  56int rt28xx_open(struct net_device *net_dev);
  57
  58/* private function prototype */
  59static int rt28xx_send_packets(IN struct sk_buff *skb_p,
  60                               IN struct net_device *net_dev);
  61
  62static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
  63                                                       *net_dev);
  64
  65/*
  66========================================================================
  67Routine Description:
  68    Close raxx interface.
  69
  70Arguments:
  71        *net_dev                        the raxx interface pointer
  72
  73Return Value:
  74    0                                   Open OK
  75        otherwise                       Open Fail
  76
  77Note:
  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*/
  85int 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========================================================================
 151Routine Description:
 152    Open raxx interface.
 153
 154Arguments:
 155        *net_dev                        the raxx interface pointer
 156
 157Return Value:
 158    0                                   Open OK
 159        otherwise                       Open Fail
 160
 161Note:
 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*/
 169int 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========================================================================
 194Routine Description:
 195    Close raxx interface.
 196
 197Arguments:
 198        *net_dev                        the raxx interface pointer
 199
 200Return Value:
 201    0                                   Open OK
 202        otherwise                       Open Fail
 203
 204Note:
 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*/
 212int 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========================================================================
 369Routine Description:
 370    Open raxx interface.
 371
 372Arguments:
 373        *net_dev                        the raxx interface pointer
 374
 375Return Value:
 376    0                                   Open OK
 377        otherwise                       Open Fail
 378
 379Note:
 380========================================================================
 381*/
 382int 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
 445err:
 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
 452static 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
 463struct 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        return net_dev;
 488
 489}
 490
 491/*
 492========================================================================
 493Routine Description:
 494    The entry point for Linux kernel sent packet to our driver.
 495
 496Arguments:
 497    sk_buff *skb                the pointer refer to a sk_buffer.
 498
 499Return Value:
 500    0
 501
 502Note:
 503        This function is the entry point of Tx Path for Os delivery packet to
 504        our driver. You only can put OS-depened & STA/AP common handle procedures
 505        in here.
 506========================================================================
 507*/
 508int rt28xx_packet_xmit(struct sk_buff *skb)
 509{
 510        struct net_device *net_dev = skb->dev;
 511        struct rt_rtmp_adapter *pAd = NULL;
 512        int status = NETDEV_TX_OK;
 513        void *pPacket = (void *)skb;
 514
 515        GET_PAD_FROM_NET_DEV(pAd, net_dev);
 516
 517        /* RT2870STA does this in RTMPSendPackets() */
 518
 519        {
 520                /* Drop send request since we are in monitor mode */
 521                if (MONITOR_ON(pAd)) {
 522                        RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 523                        goto done;
 524                }
 525        }
 526
 527        /* EapolStart size is 18 */
 528        if (skb->len < 14) {
 529                /*printk("bad packet size: %d\n", pkt->len); */
 530                hex_dump("bad packet", skb->data, skb->len);
 531                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
 532                goto done;
 533        }
 534
 535        RTMP_SET_PACKET_5VT(pPacket, 0);
 536        STASendPackets((void *)pAd, (void **)&pPacket, 1);
 537
 538        status = NETDEV_TX_OK;
 539done:
 540
 541        return status;
 542}
 543
 544/*
 545========================================================================
 546Routine Description:
 547    Send a packet to WLAN.
 548
 549Arguments:
 550    skb_p           points to our adapter
 551    dev_p           which WLAN network interface
 552
 553Return Value:
 554    0: transmit successfully
 555    otherwise: transmit fail
 556
 557Note:
 558========================================================================
 559*/
 560static int rt28xx_send_packets(IN struct sk_buff *skb_p,
 561                               IN struct net_device *net_dev)
 562{
 563        struct rt_rtmp_adapter *pAd = NULL;
 564
 565        GET_PAD_FROM_NET_DEV(pAd, net_dev);
 566
 567        if (!(net_dev->flags & IFF_UP)) {
 568                RELEASE_NDIS_PACKET(pAd, (void *)skb_p,
 569                                    NDIS_STATUS_FAILURE);
 570                return NETDEV_TX_OK;
 571        }
 572
 573        NdisZeroMemory((u8 *)&skb_p->cb[CB_OFF], 15);
 574        RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
 575
 576        return rt28xx_packet_xmit(skb_p);
 577}
 578
 579/* This function will be called when query /proc */
 580struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev)
 581{
 582        struct rt_rtmp_adapter *pAd = NULL;
 583
 584        GET_PAD_FROM_NET_DEV(pAd, net_dev);
 585
 586        DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
 587
 588        pAd->iw_stats.status = 0;       /* Status - device dependent for now */
 589
 590        /* link quality */
 591        if (pAd->OpMode == OPMODE_STA)
 592                pAd->iw_stats.qual.qual =
 593                    ((pAd->Mlme.ChannelQuality * 12) / 10 + 10);
 594
 595        if (pAd->iw_stats.qual.qual > 100)
 596                pAd->iw_stats.qual.qual = 100;
 597
 598        if (pAd->OpMode == OPMODE_STA) {
 599                pAd->iw_stats.qual.level =
 600                    RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
 601                                pAd->StaCfg.RssiSample.LastRssi1,
 602                                pAd->StaCfg.RssiSample.LastRssi2);
 603        }
 604
 605        pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66];      /* noise level (dBm) */
 606
 607        pAd->iw_stats.qual.noise += 256 - 143;
 608        pAd->iw_stats.qual.updated = 1; /* Flags to know if updated */
 609#ifdef IW_QUAL_DBM
 610        pAd->iw_stats.qual.updated |= IW_QUAL_DBM;      /* Level + Noise are dBm */
 611#endif /* IW_QUAL_DBM // */
 612
 613        pAd->iw_stats.discard.nwid = 0; /* Rx : Wrong nwid/essid */
 614        pAd->iw_stats.miss.beacon = 0;  /* Missed beacons/superframe */
 615
 616        DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
 617        return &pAd->iw_stats;
 618}
 619
 620void tbtt_tasklet(unsigned long data)
 621{
 622/*#define MAX_TX_IN_TBTT                (16) */
 623
 624}
 625
 626/*
 627    ========================================================================
 628
 629    Routine Description:
 630        return ethernet statistics counter
 631
 632    Arguments:
 633        net_dev                         Pointer to net_device
 634
 635    Return Value:
 636        net_device_stats*
 637
 638    Note:
 639
 640    ========================================================================
 641*/
 642static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
 643                                                       *net_dev)
 644{
 645        struct rt_rtmp_adapter *pAd = NULL;
 646
 647        if (net_dev)
 648                GET_PAD_FROM_NET_DEV(pAd, net_dev);
 649
 650        if (pAd) {
 651
 652                pAd->stats.rx_packets =
 653                    pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
 654                pAd->stats.tx_packets =
 655                    pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
 656
 657                pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
 658                pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
 659
 660                pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
 661                pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
 662
 663                pAd->stats.rx_dropped = 0;
 664                pAd->stats.tx_dropped = 0;
 665
 666                pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;  /* multicast packets received */
 667                pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;      /* Collision packets */
 668
 669                pAd->stats.rx_length_errors = 0;
 670                pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;       /* receiver ring buff overflow */
 671                pAd->stats.rx_crc_errors = 0;   /*pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error */
 672                pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;      /* recv'd frame alignment error */
 673                pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;       /* recv'r fifo overrun */
 674                pAd->stats.rx_missed_errors = 0;        /* receiver missed packet */
 675
 676                /* detailed tx_errors */
 677                pAd->stats.tx_aborted_errors = 0;
 678                pAd->stats.tx_carrier_errors = 0;
 679                pAd->stats.tx_fifo_errors = 0;
 680                pAd->stats.tx_heartbeat_errors = 0;
 681                pAd->stats.tx_window_errors = 0;
 682
 683                /* for cslip etc */
 684                pAd->stats.rx_compressed = 0;
 685                pAd->stats.tx_compressed = 0;
 686
 687                return &pAd->stats;
 688        } else
 689                return NULL;
 690}
 691
 692BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
 693{
 694
 695        /* Unregister network device */
 696        if (net_dev != NULL) {
 697                printk
 698                    ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
 699                     net_dev->name);
 700                RtmpOSNetDevDetach(net_dev);
 701        }
 702
 703        return TRUE;
 704
 705}
 706
 707/*
 708========================================================================
 709Routine Description:
 710    Allocate memory for adapter control block.
 711
 712Arguments:
 713    pAd                                 Pointer to our adapter
 714
 715Return Value:
 716        NDIS_STATUS_SUCCESS
 717        NDIS_STATUS_FAILURE
 718        NDIS_STATUS_RESOURCES
 719
 720Note:
 721========================================================================
 722*/
 723int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
 724{
 725
 726        *ppAd = vmalloc(sizeof(struct rt_rtmp_adapter));
 727        /* 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}
 737