linux/drivers/staging/rt3070/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    --------    ----------      ----------------------------------------------
  36        Sample          Mar/21/07               Merge RT2870 and RT2860 drivers.
  37*/
  38
  39#include "rt_config.h"
  40
  41#define FORTY_MHZ_INTOLERANT_INTERVAL   (60*1000) // 1 min
  42
  43#ifdef MULTIPLE_CARD_SUPPORT
  44// record whether the card in the card list is used in the card file
  45UINT8  MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
  46// record used card mac address in the card list
  47static UINT8  MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
  48#endif // MULTIPLE_CARD_SUPPORT //
  49
  50#ifdef CONFIG_APSTA_MIXED_SUPPORT
  51UINT32 CW_MAX_IN_BITS;
  52#endif // CONFIG_APSTA_MIXED_SUPPORT //
  53
  54/*---------------------------------------------------------------------*/
  55/* Private Variables Used                                              */
  56/*---------------------------------------------------------------------*/
  57//static RALINK_TIMER_STRUCT     PeriodicTimer;
  58
  59char *mac = "";            // default 00:00:00:00:00:00
  60char *hostname = "";               // default CMPC
  61#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
  62MODULE_PARM (mac, "s");
  63#else
  64module_param (mac, charp, 0);
  65#endif
  66MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
  67
  68
  69/*---------------------------------------------------------------------*/
  70/* Prototypes of Functions Used                                        */
  71/*---------------------------------------------------------------------*/
  72#ifdef DOT11_N_SUPPORT
  73extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
  74extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
  75#endif // DOT11_N_SUPPORT //
  76extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
  77
  78
  79// public function prototype
  80INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
  81                                                        IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
  82
  83// private function prototype
  84static int rt28xx_init(IN struct net_device *net_dev);
  85INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
  86
  87#if LINUX_VERSION_CODE <= 0x20402       // Red Hat 7.1
  88struct net_device *alloc_netdev(
  89        int sizeof_priv,
  90        const char *mask,
  91        void (*setup)(struct net_device *));
  92#endif // LINUX_VERSION_CODE //
  93
  94static void CfgInitHook(PRTMP_ADAPTER pAd);
  95//static BOOLEAN RT28XXAvailRANameAssign(IN CHAR *name_p);
  96
  97#ifdef CONFIG_STA_SUPPORT
  98extern  const struct iw_handler_def rt28xx_iw_handler_def;
  99#endif // CONFIG_STA_SUPPORT //
 100
 101#ifdef CONFIG_APSTA_MIXED_SUPPORT
 102extern  const struct iw_handler_def rt28xx_ap_iw_handler_def;
 103#endif // CONFIG_APSTA_MIXED_SUPPORT //
 104
 105#if WIRELESS_EXT >= 12
 106// This function will be called when query /proc
 107struct iw_statistics *rt28xx_get_wireless_stats(
 108    IN struct net_device *net_dev);
 109#endif
 110
 111struct net_device_stats *RT28xx_get_ether_stats(
 112    IN  struct net_device *net_dev);
 113
 114/*
 115========================================================================
 116Routine Description:
 117    Close raxx interface.
 118
 119Arguments:
 120        *net_dev                        the raxx interface pointer
 121
 122Return Value:
 123    0                                   Open OK
 124        otherwise                       Open Fail
 125
 126Note:
 127        1. if open fail, kernel will not call the close function.
 128        2. Free memory for
 129                (1) Mlme Memory Handler:                MlmeHalt()
 130                (2) TX & RX:                                    RTMPFreeTxRxRingMemory()
 131                (3) BA Reordering:                              ba_reordering_resource_release()
 132========================================================================
 133*/
 134int MainVirtualIF_close(IN struct net_device *net_dev)
 135{
 136    RTMP_ADAPTER *pAd = net_dev->ml_priv;
 137
 138        // Sanity check for pAd
 139        if (pAd == NULL)
 140                return 0; // close ok
 141
 142        netif_carrier_off(pAd->net_dev);
 143        netif_stop_queue(pAd->net_dev);
 144
 145
 146
 147        VIRTUAL_IF_DOWN(pAd);
 148
 149        RT_MOD_DEC_USE_COUNT();
 150
 151        return 0; // close ok
 152}
 153
 154/*
 155========================================================================
 156Routine Description:
 157    Open raxx interface.
 158
 159Arguments:
 160        *net_dev                        the raxx interface pointer
 161
 162Return Value:
 163    0                                   Open OK
 164        otherwise                       Open Fail
 165
 166Note:
 167        1. if open fail, kernel will not call the close function.
 168        2. Free memory for
 169                (1) Mlme Memory Handler:                MlmeHalt()
 170                (2) TX & RX:                                    RTMPFreeTxRxRingMemory()
 171                (3) BA Reordering:                              ba_reordering_resource_release()
 172========================================================================
 173*/
 174int MainVirtualIF_open(IN struct net_device *net_dev)
 175{
 176    RTMP_ADAPTER *pAd = net_dev->ml_priv;
 177
 178        // Sanity check for pAd
 179        if (pAd == NULL)
 180                return 0; // close ok
 181
 182        if (VIRTUAL_IF_UP(pAd) != 0)
 183                return -1;
 184
 185        // increase MODULE use count
 186        RT_MOD_INC_USE_COUNT();
 187
 188        netif_start_queue(net_dev);
 189        netif_carrier_on(net_dev);
 190        netif_wake_queue(net_dev);
 191
 192        return 0;
 193}
 194
 195/*
 196========================================================================
 197Routine Description:
 198    Close raxx interface.
 199
 200Arguments:
 201        *net_dev                        the raxx interface pointer
 202
 203Return Value:
 204    0                                   Open OK
 205        otherwise                       Open Fail
 206
 207Note:
 208        1. if open fail, kernel will not call the close function.
 209        2. Free memory for
 210                (1) Mlme Memory Handler:                MlmeHalt()
 211                (2) TX & RX:                                    RTMPFreeTxRxRingMemory()
 212                (3) BA Reordering:                              ba_reordering_resource_release()
 213========================================================================
 214*/
 215int rt28xx_close(IN PNET_DEV dev)
 216{
 217        struct net_device * net_dev = (struct net_device *)dev;
 218    RTMP_ADAPTER        *pAd = net_dev->ml_priv;
 219        BOOLEAN                 Cancelled = FALSE;
 220        UINT32                  i = 0;
 221#ifdef RT2870
 222        DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
 223        DECLARE_WAITQUEUE(wait, current);
 224
 225        //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
 226#endif // RT2870 //
 227
 228
 229    DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
 230
 231        // Sanity check for pAd
 232        if (pAd == NULL)
 233                return 0; // close ok
 234
 235
 236#ifdef WDS_SUPPORT
 237        WdsDown(pAd);
 238#endif // WDS_SUPPORT //
 239
 240#ifdef CONFIG_STA_SUPPORT
 241        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 242        {
 243
 244                // If dirver doesn't wake up firmware here,
 245                // NICLoadFirmware will hang forever when interface is up again.
 246                if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
 247        {
 248                    AsicForceWakeup(pAd, TRUE);
 249        }
 250
 251#ifdef QOS_DLS_SUPPORT
 252                // send DLS-TEAR_DOWN message,
 253                if (pAd->CommonCfg.bDLSCapable)
 254                {
 255                        UCHAR i;
 256
 257                        // tear down local dls table entry
 258                        for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
 259                        {
 260                                if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
 261                                {
 262                                        RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
 263                                        pAd->StaCfg.DLSEntry[i].Status  = DLS_NONE;
 264                                        pAd->StaCfg.DLSEntry[i].Valid   = FALSE;
 265                                }
 266                        }
 267
 268                        // tear down peer dls table entry
 269                        for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
 270                        {
 271                                if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
 272                                {
 273                                        RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
 274                                        pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
 275                                        pAd->StaCfg.DLSEntry[i].Valid   = FALSE;
 276                                }
 277                        }
 278                        RT28XX_MLME_HANDLER(pAd);
 279                }
 280#endif // QOS_DLS_SUPPORT //
 281
 282                if (INFRA_ON(pAd) &&
 283                        (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
 284                {
 285                        MLME_DISASSOC_REQ_STRUCT        DisReq;
 286                        MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
 287
 288                        COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
 289                        DisReq.Reason =  REASON_DEAUTH_STA_LEAVING;
 290
 291                        MsgElem->Machine = ASSOC_STATE_MACHINE;
 292                        MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
 293                        MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
 294                        NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
 295
 296                        // Prevent to connect AP again in STAMlmePeriodicExec
 297                        pAd->MlmeAux.AutoReconnectSsidLen= 32;
 298                        NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
 299
 300                        pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
 301                        MlmeDisassocReqAction(pAd, MsgElem);
 302                        kfree(MsgElem);
 303
 304                        RTMPusecDelay(1000);
 305                }
 306
 307#ifdef RT2870
 308        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
 309#endif // RT2870 //
 310
 311#ifdef CCX_SUPPORT
 312                RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
 313#endif
 314
 315                RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
 316                RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
 317
 318#ifdef WPA_SUPPLICANT_SUPPORT
 319#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
 320                {
 321                        union iwreq_data    wrqu;
 322                        // send wireless event to wpa_supplicant for infroming interface down.
 323                        memset(&wrqu, 0, sizeof(wrqu));
 324                        wrqu.data.flags = RT_INTERFACE_DOWN;
 325                        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
 326                }
 327#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
 328#endif // WPA_SUPPLICANT_SUPPORT //
 329
 330                MlmeRadioOff(pAd);
 331        }
 332#endif // CONFIG_STA_SUPPORT //
 333
 334        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 335
 336        for (i = 0 ; i < NUM_OF_TX_RING; i++)
 337        {
 338                while (pAd->DeQueueRunning[i] == TRUE)
 339                {
 340                        printk("Waiting for TxQueue[%d] done..........\n", i);
 341                        RTMPusecDelay(1000);
 342                }
 343        }
 344
 345#ifdef RT2870
 346        // ensure there are no more active urbs.
 347        add_wait_queue (&unlink_wakeup, &wait);
 348        pAd->wait = &unlink_wakeup;
 349
 350        // maybe wait for deletions to finish.
 351        i = 0;
 352        //while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
 353        while(i < 25)
 354        {
 355                unsigned long IrqFlags;
 356
 357                RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
 358                if (pAd->PendingRx == 0)
 359                {
 360                        RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 361                        break;
 362                }
 363                RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
 364
 365#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
 366                msleep(UNLINK_TIMEOUT_MS);      //Time in millisecond
 367#else
 368                RTMPusecDelay(UNLINK_TIMEOUT_MS*1000);  //Time in microsecond
 369#endif
 370                i++;
 371        }
 372        pAd->wait = NULL;
 373        remove_wait_queue (&unlink_wakeup, &wait);
 374#endif // RT2870 //
 375
 376        //RTUSBCleanUpMLMEWaitQueue(pAd);       /*not used in RT28xx*/
 377
 378
 379#ifdef RT2870
 380        // We need clear timerQ related structure before exits of the timer thread.
 381        RT2870_TimerQ_Exit(pAd);
 382        // Close kernel threads or tasklets
 383        RT28xxThreadTerminate(pAd);
 384#endif // RT2870 //
 385
 386        // Stop Mlme state machine
 387        MlmeHalt(pAd);
 388
 389        // Close kernel threads or tasklets
 390        kill_thread_task(pAd);
 391
 392
 393#ifdef CONFIG_STA_SUPPORT
 394        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 395        {
 396                MacTableReset(pAd);
 397        }
 398#endif // CONFIG_STA_SUPPORT //
 399
 400
 401        MeasureReqTabExit(pAd);
 402        TpcReqTabExit(pAd);
 403
 404
 405
 406
 407        // Free Ring or USB buffers
 408        RTMPFreeTxRxRingMemory(pAd);
 409
 410        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 411
 412#ifdef DOT11_N_SUPPORT
 413        // Free BA reorder resource
 414        ba_reordering_resource_release(pAd);
 415#endif // DOT11_N_SUPPORT //
 416
 417#ifdef RT2870
 418#ifdef INF_AMAZON_SE
 419        if (pAd->UsbVendorReqBuf)
 420                os_free_mem(pAd, pAd->UsbVendorReqBuf);
 421#endif // INF_AMAZON_SE //
 422#endif // RT2870 //
 423
 424        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
 425
 426        return 0; // close ok
 427} /* End of rt28xx_close */
 428
 429static int rt28xx_init(IN struct net_device *net_dev)
 430{
 431        PRTMP_ADAPTER                   pAd = net_dev->ml_priv;
 432        UINT                                    index;
 433        UCHAR                                   TmpPhy;
 434//      ULONG                                   Value=0;
 435        NDIS_STATUS                             Status;
 436//    OID_SET_HT_PHYMODE                SetHT;
 437//      WPDMA_GLO_CFG_STRUC     GloCfg;
 438        UINT32          MacCsr0 = 0;
 439
 440#ifdef RT2870
 441#ifdef INF_AMAZON_SE
 442        init_MUTEX(&(pAd->UsbVendorReq_semaphore));
 443        os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
 444        if (pAd->UsbVendorReqBuf == NULL)
 445        {
 446                DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
 447                goto err0;
 448        }
 449#endif // INF_AMAZON_SE //
 450#endif // RT2870 //
 451
 452#ifdef DOT11_N_SUPPORT
 453        // Allocate BA Reordering memory
 454        ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
 455#endif // DOT11_N_SUPPORT //
 456
 457        // Make sure MAC gets ready.
 458        index = 0;
 459        do
 460        {
 461                RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
 462                pAd->MACVersion = MacCsr0;
 463
 464                if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
 465                        break;
 466
 467                RTMPusecDelay(10);
 468        } while (index++ < 100);
 469
 470        DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
 471/*Iverson patch PCIE L1 issue */
 472
 473        // Disable DMA
 474        RT28XXDMADisable(pAd);
 475
 476
 477        // Load 8051 firmware
 478        Status = NICLoadFirmware(pAd);
 479        if (Status != NDIS_STATUS_SUCCESS)
 480        {
 481                DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
 482                goto err1;
 483        }
 484
 485        NICLoadRateSwitchingParams(pAd);
 486
 487        // Disable interrupts here which is as soon as possible
 488        // This statement should never be true. We might consider to remove it later
 489
 490        Status = RTMPAllocTxRxRingMemory(pAd);
 491        if (Status != NDIS_STATUS_SUCCESS)
 492        {
 493                DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
 494                goto err1;
 495        }
 496
 497        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
 498
 499        // initialize MLME
 500        //
 501
 502        Status = MlmeInit(pAd);
 503        if (Status != NDIS_STATUS_SUCCESS)
 504        {
 505                DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
 506                goto err2;
 507        }
 508
 509        // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
 510        //
 511        UserCfgInit(pAd);
 512
 513#ifdef RT2870
 514        // We need init timerQ related structure before create the timer thread.
 515        RT2870_TimerQ_Init(pAd);
 516#endif // RT2870 //
 517
 518        RT28XX_TASK_THREAD_INIT(pAd, Status);
 519        if (Status != NDIS_STATUS_SUCCESS)
 520                goto err1;
 521
 522//      COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
 523//      pAd->bForcePrintTX = TRUE;
 524
 525        CfgInitHook(pAd);
 526
 527
 528#ifdef BLOCK_NET_IF
 529        initblockQueueTab(pAd);
 530#endif // BLOCK_NET_IF //
 531
 532#ifdef CONFIG_STA_SUPPORT
 533        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 534                NdisAllocateSpinLock(&pAd->MacTabLock);
 535#endif // CONFIG_STA_SUPPORT //
 536
 537        MeasureReqTabInit(pAd);
 538        TpcReqTabInit(pAd);
 539
 540        //
 541        // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
 542        //
 543        Status = NICInitializeAdapter(pAd, TRUE);
 544        if (Status != NDIS_STATUS_SUCCESS)
 545        {
 546                DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
 547                if (Status != NDIS_STATUS_SUCCESS)
 548                goto err3;
 549        }
 550
 551        // Read parameters from Config File
 552        Status = RTMPReadParametersHook(pAd);
 553
 554        printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
 555        if (Status != NDIS_STATUS_SUCCESS)
 556        {
 557                DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
 558                goto err4;
 559        }
 560
 561#ifdef RT2870
 562        pAd->CommonCfg.bMultipleIRP = FALSE;
 563
 564        if (pAd->CommonCfg.bMultipleIRP)
 565                pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
 566        else
 567                pAd->CommonCfg.NumOfBulkInIRP = 1;
 568#endif // RT2870 //
 569
 570
 571        //Init Ba Capability parameters.
 572//      RT28XX_BA_INIT(pAd);
 573#ifdef DOT11_N_SUPPORT
 574        pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
 575        pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
 576        pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
 577        pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
 578        // UPdata to HT IE
 579        pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
 580        pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
 581        pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
 582#endif // DOT11_N_SUPPORT //
 583
 584        // after reading Registry, we now know if in AP mode or STA mode
 585
 586        // Load 8051 firmware; crash when FW image not existent
 587        // Status = NICLoadFirmware(pAd);
 588        // if (Status != NDIS_STATUS_SUCCESS)
 589        //    break;
 590
 591        printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
 592
 593        // We should read EEPROM for all cases.  rt2860b
 594        NICReadEEPROMParameters(pAd, mac);
 595#ifdef CONFIG_STA_SUPPORT
 596#endif // CONFIG_STA_SUPPORT //
 597
 598        printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
 599
 600        NICInitAsicFromEEPROM(pAd); //rt2860b
 601
 602        // Set PHY to appropriate mode
 603        TmpPhy = pAd->CommonCfg.PhyMode;
 604        pAd->CommonCfg.PhyMode = 0xff;
 605        RTMPSetPhyMode(pAd, TmpPhy);
 606#ifdef DOT11_N_SUPPORT
 607        SetCommonHT(pAd);
 608#endif // DOT11_N_SUPPORT //
 609
 610        // No valid channels.
 611        if (pAd->ChannelListNum == 0)
 612        {
 613                printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
 614                goto err4;
 615        }
 616
 617#ifdef DOT11_N_SUPPORT
 618        printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
 619           pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
 620           pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
 621#endif // DOT11_N_SUPPORT //
 622
 623#ifdef RT30xx
 624    //Init RT30xx RFRegisters after read RFIC type from EEPROM
 625        NICInitRT30xxRFRegisters(pAd);
 626#endif // RT30xx //
 627
 628//              APInitialize(pAd);
 629
 630#ifdef IKANOS_VX_1X0
 631        VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
 632#endif // IKANOS_VX_1X0 //
 633
 634                //
 635        // Initialize RF register to default value
 636        //
 637        AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
 638        AsicLockChannel(pAd, pAd->CommonCfg.Channel);
 639
 640        if (pAd && (Status != NDIS_STATUS_SUCCESS))
 641        {
 642                //
 643                // Undo everything if it failed
 644                //
 645                if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
 646                {
 647//                      NdisMDeregisterInterrupt(&pAd->Interrupt);
 648                        RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
 649                }
 650//              RTMPFreeAdapter(pAd); // we will free it in disconnect()
 651        }
 652        else if (pAd)
 653        {
 654                // Microsoft HCT require driver send a disconnect event after driver initialization.
 655                OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
 656//              pAd->IndicateMediaState = NdisMediaStateDisconnected;
 657                RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
 658
 659                DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
 660
 661
 662#ifdef RT2870
 663                RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
 664                RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
 665
 666                //
 667                // Support multiple BulkIn IRP,
 668                // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
 669                //
 670                for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
 671                {
 672                        RTUSBBulkReceive(pAd);
 673                        DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
 674                }
 675#endif // RT2870 //
 676        }// end of else
 677
 678
 679        DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
 680
 681        return TRUE;
 682
 683
 684err4:
 685err3:
 686        MlmeHalt(pAd);
 687err2:
 688        RTMPFreeTxRxRingMemory(pAd);
 689//      RTMPFreeAdapter(pAd);
 690err1:
 691
 692#ifdef DOT11_N_SUPPORT
 693        os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
 694#endif // DOT11_N_SUPPORT //
 695        RT28XX_IRQ_RELEASE(net_dev);
 696
 697        // shall not set priv to NULL here because the priv didn't been free yet.
 698        //net_dev->ml_priv = 0;
 699#ifdef INF_AMAZON_SE
 700err0:
 701#endif // INF_AMAZON_SE //
 702        printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
 703        return FALSE;
 704} /* End of rt28xx_init */
 705
 706
 707/*
 708========================================================================
 709Routine Description:
 710    Open raxx interface.
 711
 712Arguments:
 713        *net_dev                        the raxx interface pointer
 714
 715Return Value:
 716    0                                   Open OK
 717        otherwise                       Open Fail
 718
 719Note:
 720========================================================================
 721*/
 722int rt28xx_open(IN PNET_DEV dev)
 723{
 724        struct net_device * net_dev = (struct net_device *)dev;
 725        PRTMP_ADAPTER pAd = net_dev->ml_priv;
 726        int retval = 0;
 727        POS_COOKIE pObj;
 728
 729
 730        // Sanity check for pAd
 731        if (pAd == NULL)
 732        {
 733                /* if 1st open fail, pAd will be free;
 734                   So the net_dev->ml_priv will be NULL in 2rd open */
 735                return -1;
 736        }
 737
 738#ifdef CONFIG_APSTA_MIXED_SUPPORT
 739        if (pAd->OpMode == OPMODE_AP)
 740        {
 741                CW_MAX_IN_BITS = 6;
 742        }
 743        else if (pAd->OpMode == OPMODE_STA)
 744        {
 745                CW_MAX_IN_BITS = 10;
 746        }
 747
 748#if WIRELESS_EXT >= 12
 749        if (net_dev->ml_priv_flags == INT_MAIN)
 750        {
 751                if (pAd->OpMode == OPMODE_AP)
 752                        net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
 753                else if (pAd->OpMode == OPMODE_STA)
 754                        net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
 755        }
 756#endif // WIRELESS_EXT >= 12 //
 757#endif // CONFIG_APSTA_MIXED_SUPPORT //
 758
 759#ifdef CONFIG_STA_SUPPORT
 760#endif // CONFIG_STA_SUPPORT //
 761
 762        // Init
 763        pObj = (POS_COOKIE)pAd->OS_Cookie;
 764
 765        // reset Adapter flags
 766        RTMP_CLEAR_FLAGS(pAd);
 767
 768        // Request interrupt service routine for PCI device
 769        // register the interrupt routine with the os
 770        RT28XX_IRQ_REQUEST(net_dev);
 771
 772
 773        // Init BssTab & ChannelInfo tabbles for auto channel select.
 774
 775
 776        // Chip & other init
 777        if (rt28xx_init(net_dev) == FALSE)
 778                goto err;
 779
 780#ifdef CONFIG_STA_SUPPORT
 781        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 782        {
 783                NdisZeroMemory(pAd->StaCfg.dev_name, 16);
 784                NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
 785        }
 786#endif // CONFIG_STA_SUPPORT //
 787
 788        // Set up the Mac address
 789        NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
 790
 791        // Init IRQ parameters
 792        RT28XX_IRQ_INIT(pAd);
 793
 794        // Various AP function init
 795
 796
 797
 798#ifdef CONFIG_STA_SUPPORT
 799        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
 800        {
 801#ifdef WPA_SUPPLICANT_SUPPORT
 802#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
 803                {
 804                        union iwreq_data    wrqu;
 805                        // send wireless event to wpa_supplicant for infroming interface down.
 806                        memset(&wrqu, 0, sizeof(wrqu));
 807                        wrqu.data.flags = RT_INTERFACE_UP;
 808                        wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
 809                }
 810#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
 811#endif // WPA_SUPPLICANT_SUPPORT //
 812
 813        }
 814#endif // CONFIG_STA_SUPPORT //
 815
 816        // Enable Interrupt
 817        RT28XX_IRQ_ENABLE(pAd);
 818
 819        // Now Enable RxTx
 820        RTMPEnableRxTx(pAd);
 821        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
 822
 823        {
 824        UINT32 reg = 0;
 825        RTMP_IO_READ32(pAd, 0x1300, &reg);  // clear garbage interrupts
 826        printk("0x1300 = %08x\n", reg);
 827        }
 828
 829        {
 830//      u32 reg;
 831//      u8  byte;
 832//      u16 tmp;
 833
 834//      RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
 835
 836//      tmp = 0x0805;
 837//      reg  = (reg & 0xffff0000) | tmp;
 838//      RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
 839
 840        }
 841
 842#ifdef CONFIG_STA_SUPPORT
 843#endif // CONFIG_STA_SUPPORT //
 844
 845        return (retval);
 846
 847err:
 848        return (-1);
 849} /* End of rt28xx_open */
 850
 851static const struct net_device_ops rt3070_netdev_ops = {
 852        .ndo_open               = MainVirtualIF_open,
 853        .ndo_stop               = MainVirtualIF_close,
 854        .ndo_do_ioctl           = rt28xx_ioctl,
 855        .ndo_get_stats          = RT28xx_get_ether_stats,
 856        .ndo_validate_addr      = NULL,
 857        .ndo_set_mac_address    = eth_mac_addr,
 858        .ndo_change_mtu         = eth_change_mtu,
 859#ifdef IKANOS_VX_1X0
 860        .ndo_start_xmit         = IKANOS_DataFramesTx,
 861#else
 862        .ndo_start_xmit         = rt28xx_send_packets,
 863#endif
 864};
 865
 866/* Must not be called for mdev and apdev */
 867static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
 868{
 869        NDIS_STATUS Status;
 870        INT     i=0;
 871        CHAR    slot_name[IFNAMSIZ];
 872        struct net_device   *device;
 873
 874
 875        //ether_setup(dev);
 876//      dev->set_multicast_list = ieee80211_set_multicast_list;
 877//      dev->change_mtu = ieee80211_change_mtu;
 878#ifdef CONFIG_STA_SUPPORT
 879#if WIRELESS_EXT >= 12
 880        if (pAd->OpMode == OPMODE_STA)
 881        {
 882                dev->wireless_handlers = &rt28xx_iw_handler_def;
 883        }
 884#endif //WIRELESS_EXT >= 12
 885#endif // CONFIG_STA_SUPPORT //
 886
 887#ifdef CONFIG_APSTA_MIXED_SUPPORT
 888#if WIRELESS_EXT >= 12
 889        if (pAd->OpMode == OPMODE_AP)
 890        {
 891                dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
 892        }
 893#endif //WIRELESS_EXT >= 12
 894#endif // CONFIG_APSTA_MIXED_SUPPORT //
 895
 896#if WIRELESS_EXT < 21
 897                dev->get_wireless_stats = rt28xx_get_wireless_stats;
 898#endif
 899//      dev->uninit = ieee80211_if_reinit;
 900//      dev->destructor = ieee80211_if_free;
 901        dev->priv_flags = INT_MAIN;
 902        dev->netdev_ops = &rt3070_netdev_ops;
 903        // find available device name
 904        for (i = 0; i < 8; i++)
 905        {
 906#ifdef MULTIPLE_CARD_SUPPORT
 907                if (pAd->MC_RowID >= 0)
 908                        sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
 909                else
 910#endif // MULTIPLE_CARD_SUPPORT //
 911                sprintf(slot_name, "ra%d", i);
 912
 913#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 914#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
 915#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
 916        device = dev_get_by_name(dev_net(dev), slot_name);
 917#else
 918        device = dev_get_by_name(dev->nd_net, slot_name);
 919#endif
 920#else
 921                device = dev_get_by_name(slot_name);
 922#endif
 923                if (device != NULL) dev_put(device);
 924#else
 925                for (device = dev_base; device != NULL; device = device->next)
 926                {
 927                        if (strncmp(device->name, slot_name, 4) == 0)
 928                                break;
 929                }
 930#endif
 931                if(device == NULL)
 932                        break;
 933        }
 934
 935        if(i == 8)
 936        {
 937                DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
 938                Status = NDIS_STATUS_FAILURE;
 939        }
 940        else
 941        {
 942#ifdef MULTIPLE_CARD_SUPPORT
 943                if (pAd->MC_RowID >= 0)
 944                sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
 945                else
 946#endif // MULTIPLE_CARD_SUPPORT //
 947                sprintf(dev->name, "ra%d", i);
 948                Status = NDIS_STATUS_SUCCESS;
 949        }
 950
 951        return Status;
 952
 953}
 954
 955
 956#ifdef MULTIPLE_CARD_SUPPORT
 957/*
 958========================================================================
 959Routine Description:
 960    Get card profile path.
 961
 962Arguments:
 963    pAd
 964
 965Return Value:
 966    TRUE                - Find a card profile
 967        FALSE           - use default profile
 968
 969Note:
 970========================================================================
 971*/
 972extern INT RTMPGetKeyParameter(
 973    IN  PCHAR   key,
 974    OUT PCHAR   dest,
 975    IN  INT     destsize,
 976    IN  PCHAR   buffer);
 977
 978BOOLEAN RTMP_CardInfoRead(
 979        IN      PRTMP_ADAPTER pAd)
 980{
 981#define MC_SELECT_CARDID                0       /* use CARD ID (0 ~ 31) to identify different cards */
 982#define MC_SELECT_MAC                   1       /* use CARD MAC to identify different cards */
 983#define MC_SELECT_CARDTYPE              2       /* use CARD type (abgn or bgn) to identify different cards */
 984
 985#define LETTER_CASE_TRANSLATE(txt_p, card_id)                   \
 986        {       UINT32 _len; char _char;                                                \
 987                for(_len=0; _len<strlen(card_id); _len++) {             \
 988                        _char = *(txt_p + _len);                                        \
 989                        if (('A' <= _char) && (_char <= 'Z'))           \
 990                                *(txt_p+_len) = 'a'+(_char-'A');                \
 991                } }
 992
 993        struct file *srcf;
 994        INT retval, orgfsuid, orgfsgid;
 995        mm_segment_t orgfs;
 996        CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
 997        BOOLEAN flg_match_ok = FALSE;
 998        INT32 card_select_method;
 999        INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
1000        EEPROM_ANTENNA_STRUC antenna;
1001        USHORT addr01, addr23, addr45;
1002        UINT8 mac[6];
1003        UINT32 data, card_index;
1004        UCHAR *start_ptr;
1005
1006
1007        // init
1008        buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
1009        if (buffer == NULL)
1010        return FALSE;
1011
1012        tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
1013        if(tmpbuf == NULL)
1014        {
1015                kfree(buffer);
1016        return NDIS_STATUS_FAILURE;
1017        }
1018
1019        orgfsuid = current->fsuid;
1020        orgfsgid = current->fsgid;
1021        current->fsuid = current->fsgid = 0;
1022    orgfs = get_fs();
1023    set_fs(KERNEL_DS);
1024
1025        // get RF IC type
1026        RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
1027
1028        if ((data & 0x30) == 0)
1029                pAd->EEPROMAddressNum = 6;      // 93C46
1030        else if ((data & 0x30) == 0x10)
1031                pAd->EEPROMAddressNum = 8;      // 93C66
1032        else
1033                pAd->EEPROMAddressNum = 8;      // 93C86
1034
1035        //antenna.word = RTMP_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET);
1036        RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
1037
1038        if ((antenna.field.RfIcType == RFIC_2850) ||
1039                (antenna.field.RfIcType == RFIC_2750))
1040        {
1041                /* ABGN card */
1042                strcpy(RFIC_word, "abgn");
1043        }
1044        else
1045        {
1046                /* BGN card */
1047                strcpy(RFIC_word, "bgn");
1048        }
1049
1050        // get MAC address
1051        //addr01 = RTMP_EEPROM_READ16(pAd, 0x04);
1052        //addr23 = RTMP_EEPROM_READ16(pAd, 0x06);
1053        //addr45 = RTMP_EEPROM_READ16(pAd, 0x08);
1054        RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
1055        RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
1056        RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
1057
1058        mac[0] = (UCHAR)(addr01 & 0xff);
1059        mac[1] = (UCHAR)(addr01 >> 8);
1060        mac[2] = (UCHAR)(addr23 & 0xff);
1061        mac[3] = (UCHAR)(addr23 >> 8);
1062        mac[4] = (UCHAR)(addr45 & 0xff);
1063        mac[5] = (UCHAR)(addr45 >> 8);
1064
1065        // open card information file
1066        srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
1067        if (IS_ERR(srcf))
1068        {
1069                /* card information file does not exist */
1070                        DBGPRINT(RT_DEBUG_TRACE,
1071                                ("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
1072                return FALSE;
1073        }
1074
1075        if (srcf->f_op && srcf->f_op->read)
1076        {
1077                /* card information file exists so reading the card information */
1078                memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
1079                retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
1080                if (retval < 0)
1081                {
1082                        /* read fail */
1083                                DBGPRINT(RT_DEBUG_TRACE,
1084                                        ("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
1085                }
1086                else
1087                {
1088                        /* get card selection method */
1089                        memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
1090                        card_select_method = MC_SELECT_CARDTYPE; // default
1091
1092                        if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
1093                        {
1094                                if (strcmp(tmpbuf, "CARDID") == 0)
1095                                        card_select_method = MC_SELECT_CARDID;
1096                                else if (strcmp(tmpbuf, "MAC") == 0)
1097                                        card_select_method = MC_SELECT_MAC;
1098                                else if (strcmp(tmpbuf, "CARDTYPE") == 0)
1099                                        card_select_method = MC_SELECT_CARDTYPE;
1100                        }
1101
1102                        DBGPRINT(RT_DEBUG_TRACE,
1103                                        ("MC> Card Selection = %d\n", card_select_method));
1104
1105                        // init
1106                        card_free_id = -1;
1107                        card_nouse_id = -1;
1108                        card_same_mac_id = -1;
1109                        card_match_id = -1;
1110
1111                        // search current card information records
1112                        for(card_index=0;
1113                                card_index<MAX_NUM_OF_MULTIPLE_CARD;
1114                                card_index++)
1115                        {
1116                                if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1117                                        (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1118                                {
1119                                        // MAC is all-0 so the entry is available
1120                                        MC_CardUsed[card_index] = 0;
1121
1122                                        if (card_free_id < 0)
1123                                                card_free_id = card_index; // 1st free entry
1124                                }
1125                                else
1126                                {
1127                                        if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
1128                                        {
1129                                                // we find the entry with same MAC
1130                                                if (card_same_mac_id < 0)
1131                                                        card_same_mac_id = card_index; // 1st same entry
1132                                        }
1133                                        else
1134                                        {
1135                                                // MAC is not all-0 but used flag == 0
1136                                                if ((MC_CardUsed[card_index] == 0) &&
1137                                                        (card_nouse_id < 0))
1138                                                {
1139                                                        card_nouse_id = card_index; // 1st available entry
1140                                                }
1141                                        }
1142                                }
1143                        }
1144
1145                        DBGPRINT(RT_DEBUG_TRACE,
1146                                        ("MC> Free = %d, Same = %d, NOUSE = %d\n",
1147                                        card_free_id, card_same_mac_id, card_nouse_id));
1148
1149                        if ((card_same_mac_id >= 0) &&
1150                                ((card_select_method == MC_SELECT_CARDID) ||
1151                                (card_select_method == MC_SELECT_CARDTYPE)))
1152                        {
1153                                // same MAC entry is found
1154                                card_match_id = card_same_mac_id;
1155
1156                                if (card_select_method == MC_SELECT_CARDTYPE)
1157                                {
1158                                        // for CARDTYPE
1159                                        sprintf(card_id_buf, "%02dCARDTYPE%s",
1160                                                        card_match_id, RFIC_word);
1161
1162                                        if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1163                                        {
1164                                                // we found the card ID
1165                                                LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1166                                        }
1167                                }
1168                        }
1169                        else
1170                        {
1171                                // the card is 1st plug-in, try to find the match card profile
1172                                switch(card_select_method)
1173                                {
1174                                        case MC_SELECT_CARDID: // CARDID
1175                                        default:
1176                                                if (card_free_id >= 0)
1177                                                        card_match_id = card_free_id;
1178                                                else
1179                                                        card_match_id = card_nouse_id;
1180                                                break;
1181
1182                                        case MC_SELECT_MAC: // MAC
1183                                                sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
1184                                                                mac[0], mac[1], mac[2],
1185                                                                mac[3], mac[4], mac[5]);
1186
1187                                                /* try to find the key word in the card file */
1188                                                if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
1189                                                {
1190                                                        LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1191
1192                                                        /* get the row ID (2 ASCII characters) */
1193                                                        start_ptr -= 2;
1194                                                        card_id_buf[0] = *(start_ptr);
1195                                                        card_id_buf[1] = *(start_ptr+1);
1196                                                        card_id_buf[2] = 0x00;
1197
1198                                                        card_match_id = simple_strtol(card_id_buf, 0, 10);
1199                                                }
1200                                                break;
1201
1202                                        case MC_SELECT_CARDTYPE: // CARDTYPE
1203                                                card_nouse_id = -1;
1204
1205                                                for(card_index=0;
1206                                                        card_index<MAX_NUM_OF_MULTIPLE_CARD;
1207                                                        card_index++)
1208                                                {
1209                                                        sprintf(card_id_buf, "%02dCARDTYPE%s",
1210                                                                        card_index, RFIC_word);
1211
1212                                                        if ((start_ptr=rtstrstruncasecmp(buffer,
1213                                                                                                                card_id_buf)) != NULL)
1214                                                        {
1215                                                                LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
1216
1217                                                                if (MC_CardUsed[card_index] == 0)
1218                                                                {
1219                                                                        /* current the card profile is not used */
1220                                                                        if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
1221                                                                                (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
1222                                                                        {
1223                                                                                // find it and no previous card use it
1224                                                                                card_match_id = card_index;
1225                                                                                break;
1226                                                                        }
1227                                                                        else
1228                                                                        {
1229                                                                                // ever a card use it
1230                                                                                if (card_nouse_id < 0)
1231                                                                                        card_nouse_id = card_index;
1232                                                                        }
1233                                                                }
1234                                                        }
1235                                                }
1236
1237                                                // if not find a free one, use the available one
1238                                                if (card_match_id < 0)
1239                                                        card_match_id = card_nouse_id;
1240                                                break;
1241                                }
1242                        }
1243
1244                        if (card_match_id >= 0)
1245                        {
1246                                // make up search keyword
1247                                switch(card_select_method)
1248                                {
1249                                        case MC_SELECT_CARDID: // CARDID
1250                                                sprintf(card_id_buf, "%02dCARDID", card_match_id);
1251                                                break;
1252
1253                                        case MC_SELECT_MAC: // MAC
1254                                                sprintf(card_id_buf,
1255                                                                "%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
1256                                                                card_match_id,
1257                                                                mac[0], mac[1], mac[2],
1258                                                                mac[3], mac[4], mac[5]);
1259                                                break;
1260
1261                                        case MC_SELECT_CARDTYPE: // CARDTYPE
1262                                        default:
1263                                                sprintf(card_id_buf, "%02dcardtype%s",
1264                                                                card_match_id, RFIC_word);
1265                                                break;
1266                                }
1267
1268                                DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
1269
1270                                // read card file path
1271                                if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
1272                                {
1273                                        if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
1274                                        {
1275                                                // backup card information
1276                                                pAd->MC_RowID = card_match_id; /* base 0 */
1277                                                MC_CardUsed[card_match_id] = 1;
1278                                                memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
1279
1280                                                // backup card file path
1281                                                NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
1282                                                pAd->MC_FileName[strlen(tmpbuf)] = '\0';
1283                                                flg_match_ok = TRUE;
1284
1285                                                DBGPRINT(RT_DEBUG_TRACE,
1286                                                                ("Card Profile Name = %s\n", pAd->MC_FileName));
1287                                        }
1288                                        else
1289                                        {
1290                                                DBGPRINT(RT_DEBUG_ERROR,
1291                                                                ("Card Profile Name length too large!\n"));
1292                                        }
1293                                }
1294                                else
1295                                {
1296                                        DBGPRINT(RT_DEBUG_ERROR,
1297                                                        ("Can not find search key word in card.dat!\n"));
1298                                }
1299
1300                                if ((flg_match_ok != TRUE) &&
1301                                        (card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
1302                                {
1303                                        MC_CardUsed[card_match_id] = 0;
1304                                        memset(MC_CardMac[card_match_id], 0, sizeof(mac));
1305                                }
1306                        } // if (card_match_id >= 0)
1307                }
1308        }
1309
1310        // close file
1311        retval = filp_close(srcf, NULL);
1312        set_fs(orgfs);
1313        current->fsuid = orgfsuid;
1314        current->fsgid = orgfsgid;
1315        kfree(buffer);
1316        kfree(tmpbuf);
1317        return flg_match_ok;
1318}
1319#endif // MULTIPLE_CARD_SUPPORT //
1320
1321
1322/*
1323========================================================================
1324Routine Description:
1325    Probe RT28XX chipset.
1326
1327Arguments:
1328    _dev_p                              Point to the PCI or USB device
1329        _dev_id_p                       Point to the PCI or USB device ID
1330
1331Return Value:
1332    0                                   Probe OK
1333        -ENODEV                         Probe Fail
1334
1335Note:
1336========================================================================
1337*/
1338INT __devinit   rt28xx_probe(
1339    IN  void *_dev_p,
1340    IN  void *_dev_id_p,
1341        IN  UINT argc,
1342        OUT PRTMP_ADAPTER *ppAd)
1343{
1344    struct  net_device  *net_dev;
1345    PRTMP_ADAPTER       pAd = (PRTMP_ADAPTER) NULL;
1346    INT                 status;
1347        PVOID                           handle;
1348#ifdef RT2870
1349#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* kernel 2.4 series */
1350        struct usb_device *dev_p = (struct usb_device *)_dev_p;
1351#else
1352        struct usb_interface *intf = (struct usb_interface *)_dev_p;
1353        struct usb_device *dev_p = interface_to_usbdev(intf);
1354
1355        dev_p = usb_get_dev(dev_p);
1356#endif // LINUX_VERSION_CODE //
1357#endif // RT2870 //
1358
1359
1360#ifdef CONFIG_STA_SUPPORT
1361    DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
1362#endif // CONFIG_STA_SUPPORT //
1363
1364        // Check chipset vendor/product ID
1365//      if (RT28XXChipsetCheck(_dev_p) == FALSE)
1366//              goto err_out;
1367
1368#if LINUX_VERSION_CODE <= 0x20402       // Red Hat 7.1
1369    net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
1370#else
1371    net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
1372#endif
1373    if (net_dev == NULL)
1374    {
1375        printk("alloc_netdev failed\n");
1376
1377#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1378#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1379                module_put(THIS_MODULE);
1380#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
1381#else
1382                MOD_DEC_USE_COUNT;
1383#endif
1384        goto err_out;
1385    }
1386
1387// sample
1388//      if (rt_ieee80211_if_setup(net_dev) != NDIS_STATUS_SUCCESS)
1389//              goto err_out;
1390
1391#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
1392    SET_MODULE_OWNER(net_dev);
1393#endif
1394
1395        netif_stop_queue(net_dev);
1396#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
1397/* for supporting Network Manager */
1398/* Set the sysfs physical device reference for the network logical device
1399 * if set prior to registration will cause a symlink during initialization.
1400 */
1401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
1402    SET_NETDEV_DEV(net_dev, &(dev_p->dev));
1403#endif
1404#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
1405
1406        // Allocate RTMP_ADAPTER miniport adapter structure
1407        handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
1408        RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
1409
1410        status = RTMPAllocAdapterBlock(handle, &pAd);
1411        if (status != NDIS_STATUS_SUCCESS)
1412                goto err_out_free_netdev;
1413
1414        net_dev->ml_priv = (PVOID)pAd;
1415    pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
1416
1417        RT28XXNetDevInit(_dev_p, net_dev, pAd);
1418
1419#ifdef CONFIG_STA_SUPPORT
1420    pAd->StaCfg.OriDevType = net_dev->type;
1421#endif // CONFIG_STA_SUPPORT //
1422
1423        // Find and assign a free interface name, raxx
1424//      RT28XXAvailRANameAssign(net_dev->name);
1425
1426        // Post config
1427#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1428        if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
1429                goto err_out_unmap;
1430#else
1431        if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
1432                goto err_out_unmap;
1433#endif // LINUX_VERSION_CODE //
1434
1435#ifdef CONFIG_STA_SUPPORT
1436        pAd->OpMode = OPMODE_STA;
1437#endif // CONFIG_STA_SUPPORT //
1438
1439
1440#ifdef MULTIPLE_CARD_SUPPORT
1441        // find its profile path
1442        pAd->MC_RowID = -1; // use default profile path
1443        RTMP_CardInfoRead(pAd);
1444
1445        if (pAd->MC_RowID == -1)
1446#ifdef CONFIG_STA_SUPPORT
1447                strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
1448#endif // CONFIG_STA_SUPPORT //
1449
1450        DBGPRINT(RT_DEBUG_TRACE,
1451                        ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
1452#endif // MULTIPLE_CARD_SUPPORT //
1453
1454        // sample move
1455        if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
1456                goto err_out_unmap;
1457
1458    // Register this device
1459    status = register_netdev(net_dev);
1460    if (status)
1461        goto err_out_unmap;
1462
1463    // Set driver data
1464        RT28XX_DRVDATA_SET(_dev_p);
1465
1466
1467
1468        *ppAd = pAd;
1469    return 0; // probe ok
1470
1471
1472        /* --------------------------- ERROR HANDLE --------------------------- */
1473err_out_unmap:
1474        RTMPFreeAdapter(pAd);
1475        RT28XX_UNMAP();
1476
1477err_out_free_netdev:
1478#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
1479    free_netdev(net_dev);
1480#else
1481        kfree(net_dev);
1482#endif
1483
1484err_out:
1485        RT28XX_PUT_DEVICE(dev_p);
1486
1487#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
1488        return (LONG)NULL;
1489#else
1490    return -ENODEV; /* probe fail */
1491#endif // LINUX_VERSION_CODE //
1492} /* End of rt28xx_probe */
1493
1494
1495/*
1496========================================================================
1497Routine Description:
1498    The entry point for Linux kernel sent packet to our driver.
1499
1500Arguments:
1501    sk_buff *skb                the pointer refer to a sk_buffer.
1502
1503Return Value:
1504    0
1505
1506Note:
1507        This function is the entry point of Tx Path for Os delivery packet to
1508        our driver. You only can put OS-depened & STA/AP common handle procedures
1509        in here.
1510========================================================================
1511*/
1512int rt28xx_packet_xmit(struct sk_buff *skb)
1513{
1514        struct net_device *net_dev = skb->dev;
1515        PRTMP_ADAPTER pAd = net_dev->ml_priv;
1516        int status = 0;
1517        PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
1518
1519        /* RT2870STA does this in RTMPSendPackets() */
1520#ifdef RALINK_ATE
1521        if (ATE_ON(pAd))
1522        {
1523                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
1524                return 0;
1525        }
1526#endif // RALINK_ATE //
1527
1528#ifdef CONFIG_STA_SUPPORT
1529        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1530        {
1531                // Drop send request since we are in monitor mode
1532                if (MONITOR_ON(pAd))
1533                {
1534                        RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1535                        goto done;
1536                }
1537        }
1538#endif // CONFIG_STA_SUPPORT //
1539
1540        // EapolStart size is 18
1541        if (skb->len < 14)
1542        {
1543                //printk("bad packet size: %d\n", pkt->len);
1544                hex_dump("bad packet", skb->data, skb->len);
1545                RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
1546                goto done;
1547        }
1548
1549        RTMP_SET_PACKET_5VT(pPacket, 0);
1550//      MiniportMMRequest(pAd, pkt->data, pkt->len);
1551#ifdef CONFIG_5VT_ENHANCE
1552    if (*(int*)(skb->cb) == BRIDGE_TAG) {
1553                RTMP_SET_PACKET_5VT(pPacket, 1);
1554    }
1555#endif
1556
1557
1558
1559#ifdef CONFIG_STA_SUPPORT
1560        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1561        {
1562
1563                STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
1564        }
1565
1566#endif // CONFIG_STA_SUPPORT //
1567
1568        status = 0;
1569done:
1570
1571        return status;
1572}
1573
1574
1575/*
1576========================================================================
1577Routine Description:
1578    Send a packet to WLAN.
1579
1580Arguments:
1581    skb_p           points to our adapter
1582    dev_p           which WLAN network interface
1583
1584Return Value:
1585    0: transmit successfully
1586    otherwise: transmit fail
1587
1588Note:
1589========================================================================
1590*/
1591INT rt28xx_send_packets(
1592        IN struct sk_buff               *skb_p,
1593        IN struct net_device    *net_dev)
1594{
1595    RTMP_ADAPTER *pAd = net_dev->ml_priv;
1596
1597        if (!(net_dev->flags & IFF_UP))
1598        {
1599                RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
1600                return 0;
1601        }
1602
1603        NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
1604        RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
1605
1606        return rt28xx_packet_xmit(skb_p);
1607} /* End of MBSS_VirtualIF_PacketSend */
1608
1609
1610
1611
1612#if LINUX_VERSION_CODE <= 0x20402       // Red Hat 7.1
1613//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
1614struct net_device *alloc_netdev(
1615        int sizeof_priv,
1616        const char *mask,
1617        void (*setup)(struct net_device *))
1618{
1619    struct net_device   *dev;
1620    INT                                 alloc_size;
1621
1622
1623    /* ensure 32-byte alignment of the private area */
1624    alloc_size = sizeof (*dev) + sizeof_priv + 31;
1625
1626    dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
1627    if (dev == NULL)
1628    {
1629        DBGPRINT(RT_DEBUG_ERROR,
1630                                ("alloc_netdev: Unable to allocate device memory.\n"));
1631        return NULL;
1632    }
1633
1634    memset(dev, 0, alloc_size);
1635
1636    if (sizeof_priv)
1637        dev->ml_priv = (void *) (((long)(dev + 1) + 31) & ~31);
1638
1639    setup(dev);
1640    strcpy(dev->name, mask);
1641
1642    return dev;
1643}
1644#endif // LINUX_VERSION_CODE //
1645
1646
1647void CfgInitHook(PRTMP_ADAPTER pAd)
1648{
1649        pAd->bBroadComHT = TRUE;
1650} /* End of CfgInitHook */
1651
1652
1653#if WIRELESS_EXT >= 12
1654// This function will be called when query /proc
1655struct iw_statistics *rt28xx_get_wireless_stats(
1656    IN struct net_device *net_dev)
1657{
1658        PRTMP_ADAPTER pAd = net_dev->ml_priv;
1659
1660
1661        DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
1662
1663        pAd->iw_stats.status = 0; // Status - device dependent for now
1664
1665        // link quality
1666        pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
1667        if(pAd->iw_stats.qual.qual > 100)
1668                pAd->iw_stats.qual.qual = 100;
1669
1670#ifdef CONFIG_STA_SUPPORT
1671        if (pAd->OpMode == OPMODE_STA)
1672                pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
1673#endif // CONFIG_STA_SUPPORT //
1674
1675        pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
1676
1677        pAd->iw_stats.qual.noise += 256 - 143;
1678        pAd->iw_stats.qual.updated = 1;     // Flags to know if updated
1679#ifdef IW_QUAL_DBM
1680        pAd->iw_stats.qual.updated |= IW_QUAL_DBM;      // Level + Noise are dBm
1681#endif // IW_QUAL_DBM //
1682
1683        pAd->iw_stats.discard.nwid = 0;     // Rx : Wrong nwid/essid
1684        pAd->iw_stats.miss.beacon = 0;      // Missed beacons/superframe
1685
1686        DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
1687        return &pAd->iw_stats;
1688} /* End of rt28xx_get_wireless_stats */
1689#endif // WIRELESS_EXT //
1690
1691
1692
1693void tbtt_tasklet(unsigned long data)
1694{
1695#define MAX_TX_IN_TBTT          (16)
1696
1697}
1698
1699INT rt28xx_ioctl(
1700        IN      struct net_device       *net_dev,
1701        IN      OUT     struct ifreq    *rq,
1702        IN      INT                                     cmd)
1703{
1704        VIRTUAL_ADAPTER *pVirtualAd = NULL;
1705        RTMP_ADAPTER    *pAd = NULL;
1706        INT                             ret = 0;
1707
1708        if (net_dev->priv_flags == INT_MAIN)
1709        {
1710                pAd = net_dev->ml_priv;
1711        }
1712        else
1713        {
1714                pVirtualAd = net_dev->ml_priv;
1715                pAd = pVirtualAd->RtmpDev->ml_priv;
1716        }
1717
1718        if (pAd == NULL)
1719        {
1720                /* if 1st open fail, pAd will be free;
1721                   So the net_dev->ml_priv will be NULL in 2rd open */
1722                return -ENETDOWN;
1723        }
1724
1725
1726#ifdef CONFIG_STA_SUPPORT
1727        IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1728        {
1729                ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
1730        }
1731#endif // CONFIG_STA_SUPPORT //
1732
1733        return ret;
1734}
1735
1736/*
1737    ========================================================================
1738
1739    Routine Description:
1740        return ethernet statistics counter
1741
1742    Arguments:
1743        net_dev                     Pointer to net_device
1744
1745    Return Value:
1746        net_device_stats*
1747
1748    Note:
1749
1750    ========================================================================
1751*/
1752struct net_device_stats *RT28xx_get_ether_stats(
1753    IN  struct net_device *net_dev)
1754{
1755    RTMP_ADAPTER *pAd = NULL;
1756
1757        if (net_dev)
1758                pAd = net_dev->ml_priv;
1759
1760        if (pAd)
1761        {
1762
1763                pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
1764                pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
1765
1766                pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
1767                pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
1768
1769                pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
1770                pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
1771
1772                pAd->stats.rx_dropped = 0;
1773                pAd->stats.tx_dropped = 0;
1774
1775            pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;   // multicast packets received
1776            pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;  // Collision packets
1777
1778            pAd->stats.rx_length_errors = 0;
1779            pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;                   // receiver ring buff overflow
1780            pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error
1781            pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;          // recv'd frame alignment error
1782            pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;                   // recv'r fifo overrun
1783            pAd->stats.rx_missed_errors = 0;                                            // receiver missed packet
1784
1785            // detailed tx_errors
1786            pAd->stats.tx_aborted_errors = 0;
1787            pAd->stats.tx_carrier_errors = 0;
1788            pAd->stats.tx_fifo_errors = 0;
1789            pAd->stats.tx_heartbeat_errors = 0;
1790            pAd->stats.tx_window_errors = 0;
1791
1792            // for cslip etc
1793            pAd->stats.rx_compressed = 0;
1794            pAd->stats.tx_compressed = 0;
1795
1796                return &pAd->stats;
1797        }
1798        else
1799        return NULL;
1800}
1801
1802
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.