linux/drivers/staging/rtl8192e/r8192E_core.c
<<
>>
Prefs
   1/******************************************************************************
   2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
   3 * Linux device driver for RTL8190P / RTL8192E
   4 *
   5 * Based on the r8180 driver, which is:
   6 * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of version 2 of the GNU General Public License as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program; if not, write to the Free Software Foundation, Inc.,
  18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19 *
  20 * The full GNU General Public License is included in this distribution in the
  21 * file called LICENSE.
  22 *
  23 * Contact Information:
  24 * Jerry chuang <wlanfae@realtek.com>
  25 */
  26
  27
  28#undef LOOP_TEST
  29#undef RX_DONT_PASS_UL
  30#undef DEBUG_EPROM
  31#undef DEBUG_RX_VERBOSE
  32#undef DUMMY_RX
  33#undef DEBUG_ZERO_RX
  34#undef DEBUG_RX_SKB
  35#undef DEBUG_TX_FRAG
  36#undef DEBUG_RX_FRAG
  37#undef DEBUG_TX_FILLDESC
  38#undef DEBUG_TX
  39#undef DEBUG_IRQ
  40#undef DEBUG_RX
  41#undef DEBUG_RXALLOC
  42#undef DEBUG_REGISTERS
  43#undef DEBUG_RING
  44#undef DEBUG_IRQ_TASKLET
  45#undef DEBUG_TX_ALLOC
  46#undef DEBUG_TX_DESC
  47
  48//#define CONFIG_RTL8192_IO_MAP
  49#include <linux/vmalloc.h>
  50#include <asm/uaccess.h>
  51#include "r8192E_hw.h"
  52#include "r8192E.h"
  53#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */
  54#include "r8180_93cx6.h"   /* Card EEPROM */
  55#include "r8192E_wx.h"
  56#include "r819xE_phy.h" //added by WB 4.30.2008
  57#include "r819xE_phyreg.h"
  58#include "r819xE_cmdpkt.h"
  59#include "r8192E_dm.h"
  60//#include "r8192xU_phyreg.h"
  61//#include <linux/usb.h>
  62// FIXME: check if 2.6.7 is ok
  63
  64#ifdef CONFIG_PM_RTL
  65#include "r8192_pm.h"
  66#endif
  67
  68#ifdef ENABLE_DOT11D
  69#include "dot11d.h"
  70#endif
  71
  72//set here to open your trace code. //WB
  73u32 rt_global_debug_component = \
  74                //              COMP_INIT       |
  75                        //      COMP_EPROM      |
  76                //              COMP_PHY        |
  77                //              COMP_RF         |
  78                                COMP_FIRMWARE   |
  79                        //      COMP_TRACE      |
  80                //              COMP_DOWN       |
  81                //              COMP_SWBW       |
  82                //              COMP_SEC        |
  83//                              COMP_QOS        |
  84//                              COMP_RATE       |
  85                //              COMP_RECV       |
  86                //              COMP_SEND       |
  87                //              COMP_POWER      |
  88                        //      COMP_EVENTS     |
  89                        //      COMP_RESET      |
  90                        //      COMP_CMDPKT     |
  91                        //      COMP_POWER_TRACKING     |
  92                        //      COMP_INTR       |
  93                                COMP_ERR ; //always open err flags on
  94#ifndef PCI_DEVICE
  95#define PCI_DEVICE(vend,dev)\
  96        .vendor=(vend),.device=(dev),\
  97        .subvendor=PCI_ANY_ID,.subdevice=PCI_ANY_ID
  98#endif
  99static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = {
 100#ifdef RTL8190P
 101        /* Realtek */
 102        /* Dlink */
 103        { PCI_DEVICE(0x10ec, 0x8190) },
 104        /* Corega */
 105        { PCI_DEVICE(0x07aa, 0x0045) },
 106        { PCI_DEVICE(0x07aa, 0x0046) },
 107#else
 108        /* Realtek */
 109        { PCI_DEVICE(0x10ec, 0x8192) },
 110
 111        /* Corega */
 112        { PCI_DEVICE(0x07aa, 0x0044) },
 113        { PCI_DEVICE(0x07aa, 0x0047) },
 114#endif
 115        {}
 116};
 117
 118static char* ifname = "wlan%d";
 119static int hwwep = 1; //default use hw. set 0 to use software security
 120static int channels = 0x3fff;
 121
 122MODULE_LICENSE("GPL");
 123MODULE_VERSION("V 1.1");
 124MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl);
 125//MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
 126MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards");
 127
 128
 129module_param(ifname, charp, S_IRUGO|S_IWUSR );
 130//module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
 131module_param(hwwep,int, S_IRUGO|S_IWUSR);
 132module_param(channels,int, S_IRUGO|S_IWUSR);
 133
 134MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default");
 135//MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
 136MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
 137MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
 138
 139static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
 140                         const struct pci_device_id *id);
 141static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev);
 142
 143static struct pci_driver rtl8192_pci_driver = {
 144        .name           = RTL819xE_MODULE_NAME,           /* Driver name   */
 145        .id_table       = rtl8192_pci_id_tbl,             /* PCI_ID table  */
 146        .probe          = rtl8192_pci_probe,              /* probe fn      */
 147        .remove         = __devexit_p(rtl8192_pci_disconnect),    /* remove fn     */
 148#ifdef CONFIG_PM_RTL
 149        .suspend        = rtl8192E_suspend,               /* PM suspend fn */
 150        .resume         = rtl8192E_resume,                 /* PM resume fn  */
 151#else
 152        .suspend        = NULL,                           /* PM suspend fn */
 153        .resume         = NULL,                           /* PM resume fn  */
 154#endif
 155};
 156
 157#ifdef ENABLE_DOT11D
 158
 159typedef struct _CHANNEL_LIST
 160{
 161        u8      Channel[32];
 162        u8      Len;
 163}CHANNEL_LIST, *PCHANNEL_LIST;
 164
 165static CHANNEL_LIST ChannelPlan[] = {
 166        {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24},             //FCC
 167        {{1,2,3,4,5,6,7,8,9,10,11},11},                                                 //IC
 168        {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},   //ETSI
 169        {{1,2,3,4,5,6,7,8,9,10,11,12,13},13},    //Spain. Change to ETSI.
 170        {{1,2,3,4,5,6,7,8,9,10,11,12,13},13},   //France. Change to ETSI.
 171        {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},        //MKK                                   //MKK
 172        {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1
 173        {{1,2,3,4,5,6,7,8,9,10,11,12,13},13},   //Israel.
 174        {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},                        // For 11a , TELEC
 175        {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22},    //MIC
 176        {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}                                 //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
 177};
 178
 179static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv)
 180{
 181        int i, max_chan=-1, min_chan=-1;
 182        struct ieee80211_device* ieee = priv->ieee80211;
 183        switch (channel_plan)
 184        {
 185                case COUNTRY_CODE_FCC:
 186                case COUNTRY_CODE_IC:
 187                case COUNTRY_CODE_ETSI:
 188                case COUNTRY_CODE_SPAIN:
 189                case COUNTRY_CODE_FRANCE:
 190                case COUNTRY_CODE_MKK:
 191                case COUNTRY_CODE_MKK1:
 192                case COUNTRY_CODE_ISRAEL:
 193                case COUNTRY_CODE_TELEC:
 194                case COUNTRY_CODE_MIC:
 195                {
 196                        Dot11d_Init(ieee);
 197                        ieee->bGlobalDomain = false;
 198                        //acturally 8225 & 8256 rf chip only support B,G,24N mode
 199                        if ((priv->rf_chip == RF_8225) || (priv->rf_chip == RF_8256))
 200                        {
 201                                min_chan = 1;
 202                                max_chan = 14;
 203                        }
 204                        else
 205                        {
 206                                RT_TRACE(COMP_ERR, "unknown rf chip, can't set channel map in function:%s()\n", __FUNCTION__);
 207                        }
 208                        if (ChannelPlan[channel_plan].Len != 0){
 209                                // Clear old channel map
 210                                memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
 211                                // Set new channel map
 212                                for (i=0;i<ChannelPlan[channel_plan].Len;i++)
 213                                {
 214                                        if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan)
 215                                            break;
 216                                        GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
 217                                }
 218                        }
 219                        break;
 220                }
 221                case COUNTRY_CODE_GLOBAL_DOMAIN:
 222                {
 223                        GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting
 224                        Dot11d_Reset(ieee);
 225                        ieee->bGlobalDomain = true;
 226                        break;
 227                }
 228                default:
 229                        break;
 230        }
 231}
 232#endif
 233
 234
 235#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
 236/* 2007/07/25 MH Defien temp tx fw info. */
 237static TX_FWINFO_T Tmp_TxFwInfo;
 238
 239
 240#define         rx_hal_is_cck_rate(_pdrvinfo)\
 241                        (_pdrvinfo->RxRate == DESC90_RATE1M ||\
 242                        _pdrvinfo->RxRate == DESC90_RATE2M ||\
 243                        _pdrvinfo->RxRate == DESC90_RATE5_5M ||\
 244                        _pdrvinfo->RxRate == DESC90_RATE11M) &&\
 245                        !_pdrvinfo->RxHT\
 246
 247
 248void CamResetAllEntry(struct net_device *dev)
 249{
 250        //u8 ucIndex;
 251        u32 ulcommand = 0;
 252
 253#if 1
 254        ulcommand |= BIT31|BIT30;
 255        write_nic_dword(dev, RWCAM, ulcommand);
 256#else
 257        for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
 258                CAM_mark_invalid(dev, ucIndex);
 259        for(ucIndex=0;ucIndex<TOTAL_CAM_ENTRY;ucIndex++)
 260                CAM_empty_entry(dev, ucIndex);
 261#endif
 262}
 263
 264
 265void write_cam(struct net_device *dev, u8 addr, u32 data)
 266{
 267        write_nic_dword(dev, WCAMI, data);
 268        write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff) );
 269}
 270u32 read_cam(struct net_device *dev, u8 addr)
 271{
 272        write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff) );
 273        return read_nic_dword(dev, 0xa8);
 274}
 275
 276////////////////////////////////////////////////////////////
 277#ifdef CONFIG_RTL8180_IO_MAP
 278
 279u8 read_nic_byte(struct net_device *dev, int x)
 280{
 281        return 0xff&inb(dev->base_addr +x);
 282}
 283
 284u32 read_nic_dword(struct net_device *dev, int x)
 285{
 286        return inl(dev->base_addr +x);
 287}
 288
 289u16 read_nic_word(struct net_device *dev, int x)
 290{
 291        return inw(dev->base_addr +x);
 292}
 293
 294void write_nic_byte(struct net_device *dev, int x,u8 y)
 295{
 296        outb(y&0xff,dev->base_addr +x);
 297}
 298
 299void write_nic_word(struct net_device *dev, int x,u16 y)
 300{
 301        outw(y,dev->base_addr +x);
 302}
 303
 304void write_nic_dword(struct net_device *dev, int x,u32 y)
 305{
 306        outl(y,dev->base_addr +x);
 307}
 308
 309#else /* RTL_IO_MAP */
 310
 311u8 read_nic_byte(struct net_device *dev, int x)
 312{
 313        return 0xff&readb((u8*)dev->mem_start +x);
 314}
 315
 316u32 read_nic_dword(struct net_device *dev, int x)
 317{
 318        return readl((u8*)dev->mem_start +x);
 319}
 320
 321u16 read_nic_word(struct net_device *dev, int x)
 322{
 323        return readw((u8*)dev->mem_start +x);
 324}
 325
 326void write_nic_byte(struct net_device *dev, int x,u8 y)
 327{
 328        writeb(y,(u8*)dev->mem_start +x);
 329        udelay(20);
 330}
 331
 332void write_nic_dword(struct net_device *dev, int x,u32 y)
 333{
 334        writel(y,(u8*)dev->mem_start +x);
 335        udelay(20);
 336}
 337
 338void write_nic_word(struct net_device *dev, int x,u16 y)
 339{
 340        writew(y,(u8*)dev->mem_start +x);
 341        udelay(20);
 342}
 343
 344#endif /* RTL_IO_MAP */
 345
 346
 347///////////////////////////////////////////////////////////
 348
 349//u8 read_phy_cck(struct net_device *dev, u8 adr);
 350//u8 read_phy_ofdm(struct net_device *dev, u8 adr);
 351/* this might still called in what was the PHY rtl8185/rtl8192 common code
 352 * plans are to possibilty turn it again in one common code...
 353 */
 354inline void force_pci_posting(struct net_device *dev)
 355{
 356}
 357
 358
 359//warning message WB
 360irqreturn_t rtl8192_interrupt(int irq, void *netdev);
 361//static struct net_device_stats *rtl8192_stats(struct net_device *dev);
 362void rtl8192_commit(struct net_device *dev);
 363//void rtl8192_restart(struct net_device *dev);
 364void rtl8192_restart(struct work_struct *work);
 365//void rtl8192_rq_tx_ack(struct work_struct *work);
 366
 367void watch_dog_timer_callback(unsigned long data);
 368#ifdef ENABLE_IPS
 369void IPSEnter(struct net_device *dev);
 370void IPSLeave(struct net_device *dev);
 371void InactivePsWorkItemCallback(struct net_device *dev);
 372#endif
 373/****************************************************************************
 374   -----------------------------PROCFS STUFF-------------------------
 375*****************************************************************************/
 376
 377static struct proc_dir_entry *rtl8192_proc = NULL;
 378
 379
 380
 381static int proc_get_stats_ap(char *page, char **start,
 382                          off_t offset, int count,
 383                          int *eof, void *data)
 384{
 385        struct net_device *dev = data;
 386        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 387        struct ieee80211_device *ieee = priv->ieee80211;
 388        struct ieee80211_network *target;
 389
 390        int len = 0;
 391
 392        list_for_each_entry(target, &ieee->network_list, list) {
 393
 394                len += snprintf(page + len, count - len,
 395                "%s ", target->ssid);
 396
 397                if(target->wpa_ie_len>0 || target->rsn_ie_len>0){
 398                        len += snprintf(page + len, count - len,
 399                        "WPA\n");
 400                }
 401                else{
 402                        len += snprintf(page + len, count - len,
 403                        "non_WPA\n");
 404                }
 405
 406        }
 407
 408        *eof = 1;
 409        return len;
 410}
 411
 412static int proc_get_registers(char *page, char **start,
 413                          off_t offset, int count,
 414                          int *eof, void *data)
 415{
 416        struct net_device *dev = data;
 417//      struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 418
 419        int len = 0;
 420        int i,n;
 421
 422        int max=0xff;
 423
 424        /* This dump the current register page */
 425        len += snprintf(page + len, count - len,
 426                        "\n####################page 0##################\n ");
 427
 428        for(n=0;n<=max;)
 429        {
 430                //printk( "\nD: %2x> ", n);
 431                len += snprintf(page + len, count - len,
 432                        "\nD:  %2x > ",n);
 433
 434                for(i=0;i<16 && n<=max;i++,n++)
 435                len += snprintf(page + len, count - len,
 436                        "%2x ",read_nic_byte(dev,n));
 437
 438                //      printk("%2x ",read_nic_byte(dev,n));
 439        }
 440        len += snprintf(page + len, count - len,"\n");
 441        len += snprintf(page + len, count - len,
 442                        "\n####################page 1##################\n ");
 443        for(n=0;n<=max;)
 444        {
 445                //printk( "\nD: %2x> ", n);
 446                len += snprintf(page + len, count - len,
 447                        "\nD:  %2x > ",n);
 448
 449                for(i=0;i<16 && n<=max;i++,n++)
 450                len += snprintf(page + len, count - len,
 451                        "%2x ",read_nic_byte(dev,0x100|n));
 452
 453                //      printk("%2x ",read_nic_byte(dev,n));
 454        }
 455
 456        len += snprintf(page + len, count - len,
 457                        "\n####################page 3##################\n ");
 458        for(n=0;n<=max;)
 459        {
 460                //printk( "\nD: %2x> ", n);
 461                len += snprintf(page + len, count - len,
 462                        "\nD:  %2x > ",n);
 463
 464                for(i=0;i<16 && n<=max;i++,n++)
 465                len += snprintf(page + len, count - len,
 466                        "%2x ",read_nic_byte(dev,0x300|n));
 467
 468                //      printk("%2x ",read_nic_byte(dev,n));
 469        }
 470
 471
 472        *eof = 1;
 473        return len;
 474
 475}
 476
 477
 478
 479static int proc_get_stats_tx(char *page, char **start,
 480                          off_t offset, int count,
 481                          int *eof, void *data)
 482{
 483        struct net_device *dev = data;
 484        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 485
 486        int len = 0;
 487
 488        len += snprintf(page + len, count - len,
 489                "TX VI priority ok int: %lu\n"
 490//              "TX VI priority error int: %lu\n"
 491                "TX VO priority ok int: %lu\n"
 492//              "TX VO priority error int: %lu\n"
 493                "TX BE priority ok int: %lu\n"
 494//              "TX BE priority error int: %lu\n"
 495                "TX BK priority ok int: %lu\n"
 496//              "TX BK priority error int: %lu\n"
 497                "TX MANAGE priority ok int: %lu\n"
 498//              "TX MANAGE priority error int: %lu\n"
 499                "TX BEACON priority ok int: %lu\n"
 500                "TX BEACON priority error int: %lu\n"
 501                "TX CMDPKT priority ok int: %lu\n"
 502//              "TX high priority ok int: %lu\n"
 503//              "TX high priority failed error int: %lu\n"
 504//              "TX queue resume: %lu\n"
 505                "TX queue stopped?: %d\n"
 506                "TX fifo overflow: %lu\n"
 507//              "TX beacon: %lu\n"
 508//              "TX VI queue: %d\n"
 509//              "TX VO queue: %d\n"
 510//              "TX BE queue: %d\n"
 511//              "TX BK queue: %d\n"
 512//              "TX HW queue: %d\n"
 513//              "TX VI dropped: %lu\n"
 514//              "TX VO dropped: %lu\n"
 515//              "TX BE dropped: %lu\n"
 516//              "TX BK dropped: %lu\n"
 517                "TX total data packets %lu\n"
 518                "TX total data bytes :%lu\n",
 519//              "TX beacon aborted: %lu\n",
 520                priv->stats.txviokint,
 521//              priv->stats.txvierr,
 522                priv->stats.txvookint,
 523//              priv->stats.txvoerr,
 524                priv->stats.txbeokint,
 525//              priv->stats.txbeerr,
 526                priv->stats.txbkokint,
 527//              priv->stats.txbkerr,
 528                priv->stats.txmanageokint,
 529//              priv->stats.txmanageerr,
 530                priv->stats.txbeaconokint,
 531                priv->stats.txbeaconerr,
 532                priv->stats.txcmdpktokint,
 533//              priv->stats.txhpokint,
 534//              priv->stats.txhperr,
 535//              priv->stats.txresumed,
 536                netif_queue_stopped(dev),
 537                priv->stats.txoverflow,
 538//              priv->stats.txbeacon,
 539//              atomic_read(&(priv->tx_pending[VI_QUEUE])),
 540//              atomic_read(&(priv->tx_pending[VO_QUEUE])),
 541//              atomic_read(&(priv->tx_pending[BE_QUEUE])),
 542//              atomic_read(&(priv->tx_pending[BK_QUEUE])),
 543//              read_nic_byte(dev, TXFIFOCOUNT),
 544//              priv->stats.txvidrop,
 545//              priv->stats.txvodrop,
 546                priv->ieee80211->stats.tx_packets,
 547                priv->ieee80211->stats.tx_bytes
 548
 549
 550//              priv->stats.txbedrop,
 551//              priv->stats.txbkdrop
 552                        //      priv->stats.txdatapkt
 553//              priv->stats.txbeaconerr
 554                );
 555
 556        *eof = 1;
 557        return len;
 558}
 559
 560
 561
 562static int proc_get_stats_rx(char *page, char **start,
 563                          off_t offset, int count,
 564                          int *eof, void *data)
 565{
 566        struct net_device *dev = data;
 567        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 568
 569        int len = 0;
 570
 571        len += snprintf(page + len, count - len,
 572                "RX packets: %lu\n"
 573                "RX desc err: %lu\n"
 574                "RX rx overflow error: %lu\n"
 575                "RX invalid urb error: %lu\n",
 576                priv->stats.rxint,
 577                priv->stats.rxrdu,
 578                priv->stats.rxoverflow,
 579                priv->stats.rxurberr);
 580
 581        *eof = 1;
 582        return len;
 583}
 584
 585static void rtl8192_proc_module_init(void)
 586{
 587        RT_TRACE(COMP_INIT, "Initializing proc filesystem");
 588        rtl8192_proc=create_proc_entry(RTL819xE_MODULE_NAME, S_IFDIR, init_net.proc_net);
 589}
 590
 591
 592static void rtl8192_proc_module_remove(void)
 593{
 594        remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net);
 595}
 596
 597
 598static void rtl8192_proc_remove_one(struct net_device *dev)
 599{
 600        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 601
 602        printk("dev name=======> %s\n",dev->name);
 603
 604        if (priv->dir_dev) {
 605        //      remove_proc_entry("stats-hw", priv->dir_dev);
 606                remove_proc_entry("stats-tx", priv->dir_dev);
 607                remove_proc_entry("stats-rx", priv->dir_dev);
 608        //      remove_proc_entry("stats-ieee", priv->dir_dev);
 609                remove_proc_entry("stats-ap", priv->dir_dev);
 610                remove_proc_entry("registers", priv->dir_dev);
 611        //      remove_proc_entry("cck-registers",priv->dir_dev);
 612        //      remove_proc_entry("ofdm-registers",priv->dir_dev);
 613                //remove_proc_entry(dev->name, rtl8192_proc);
 614                remove_proc_entry("wlan0", rtl8192_proc);
 615                priv->dir_dev = NULL;
 616        }
 617}
 618
 619
 620static void rtl8192_proc_init_one(struct net_device *dev)
 621{
 622        struct proc_dir_entry *e;
 623        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 624        priv->dir_dev = create_proc_entry(dev->name,
 625                                          S_IFDIR | S_IRUGO | S_IXUGO,
 626                                          rtl8192_proc);
 627        if (!priv->dir_dev) {
 628                RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n",
 629                      dev->name);
 630                return;
 631        }
 632        e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
 633                                   priv->dir_dev, proc_get_stats_rx, dev);
 634
 635        if (!e) {
 636                RT_TRACE(COMP_ERR,"Unable to initialize "
 637                      "/proc/net/rtl8192/%s/stats-rx\n",
 638                      dev->name);
 639        }
 640
 641
 642        e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
 643                                   priv->dir_dev, proc_get_stats_tx, dev);
 644
 645        if (!e) {
 646                RT_TRACE(COMP_ERR, "Unable to initialize "
 647                      "/proc/net/rtl8192/%s/stats-tx\n",
 648                      dev->name);
 649        }
 650
 651        e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
 652                                   priv->dir_dev, proc_get_stats_ap, dev);
 653
 654        if (!e) {
 655                RT_TRACE(COMP_ERR, "Unable to initialize "
 656                      "/proc/net/rtl8192/%s/stats-ap\n",
 657                      dev->name);
 658        }
 659
 660        e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
 661                                   priv->dir_dev, proc_get_registers, dev);
 662        if (!e) {
 663                RT_TRACE(COMP_ERR, "Unable to initialize "
 664                      "/proc/net/rtl8192/%s/registers\n",
 665                      dev->name);
 666        }
 667}
 668/****************************************************************************
 669   -----------------------------MISC STUFF-------------------------
 670*****************************************************************************/
 671
 672short check_nic_enough_desc(struct net_device *dev, int prio)
 673{
 674    struct r8192_priv *priv = ieee80211_priv(dev);
 675    struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
 676
 677    /* for now we reserve two free descriptor as a safety boundary
 678     * between the tail and the head
 679     */
 680    if (ring->entries - skb_queue_len(&ring->queue) >= 2) {
 681        return 1;
 682    } else {
 683        return 0;
 684    }
 685}
 686
 687static void tx_timeout(struct net_device *dev)
 688{
 689        struct r8192_priv *priv = ieee80211_priv(dev);
 690        //rtl8192_commit(dev);
 691
 692        schedule_work(&priv->reset_wq);
 693        printk("TXTIMEOUT");
 694}
 695
 696
 697/****************************************************************************
 698      ------------------------------HW STUFF---------------------------
 699*****************************************************************************/
 700
 701
 702static void rtl8192_irq_enable(struct net_device *dev)
 703{
 704        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 705        priv->irq_enabled = 1;
 706        write_nic_dword(dev,INTA_MASK, priv->irq_mask);
 707}
 708
 709
 710static void rtl8192_irq_disable(struct net_device *dev)
 711{
 712        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 713
 714        write_nic_dword(dev,INTA_MASK,0);
 715        force_pci_posting(dev);
 716        priv->irq_enabled = 0;
 717}
 718
 719
 720static void rtl8192_set_mode(struct net_device *dev,int mode)
 721{
 722        u8 ecmd;
 723        ecmd=read_nic_byte(dev, EPROM_CMD);
 724        ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
 725        ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
 726        ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
 727        ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
 728        write_nic_byte(dev, EPROM_CMD, ecmd);
 729}
 730
 731
 732void rtl8192_update_msr(struct net_device *dev)
 733{
 734        struct r8192_priv *priv = ieee80211_priv(dev);
 735        u8 msr;
 736
 737        msr  = read_nic_byte(dev, MSR);
 738        msr &= ~ MSR_LINK_MASK;
 739
 740        /* do not change in link_state != WLAN_LINK_ASSOCIATED.
 741         * msr must be updated if the state is ASSOCIATING.
 742         * this is intentional and make sense for ad-hoc and
 743         * master (see the create BSS/IBSS func)
 744         */
 745        if (priv->ieee80211->state == IEEE80211_LINKED){
 746
 747                if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
 748                        msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
 749                else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
 750                        msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
 751                else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
 752                        msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
 753
 754        }else
 755                msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
 756
 757        write_nic_byte(dev, MSR, msr);
 758}
 759
 760void rtl8192_set_chan(struct net_device *dev,short ch)
 761{
 762    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 763    RT_TRACE(COMP_RF, "=====>%s()====ch:%d\n", __FUNCTION__, ch);
 764    priv->chan=ch;
 765#if 0
 766    if(priv->ieee80211->iw_mode == IW_MODE_ADHOC ||
 767            priv->ieee80211->iw_mode == IW_MODE_MASTER){
 768
 769        priv->ieee80211->link_state = WLAN_LINK_ASSOCIATED;
 770        priv->ieee80211->master_chan = ch;
 771        rtl8192_update_beacon_ch(dev);
 772    }
 773#endif
 774
 775    /* this hack should avoid frame TX during channel setting*/
 776
 777
 778    //  tx = read_nic_dword(dev,TX_CONF);
 779    //  tx &= ~TX_LOOPBACK_MASK;
 780
 781#ifndef LOOP_TEST
 782    //TODO
 783    //  write_nic_dword(dev,TX_CONF, tx |( TX_LOOPBACK_MAC<<TX_LOOPBACK_SHIFT));
 784
 785    //need to implement rf set channel here WB
 786
 787    if (priv->rf_set_chan)
 788        priv->rf_set_chan(dev,priv->chan);
 789    //  mdelay(10);
 790    //  write_nic_dword(dev,TX_CONF,tx | (TX_LOOPBACK_NONE<<TX_LOOPBACK_SHIFT));
 791#endif
 792}
 793
 794void rtl8192_rx_enable(struct net_device *dev)
 795{
 796    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 797    write_nic_dword(dev, RDQDA,priv->rx_ring_dma);
 798}
 799
 800/* the TX_DESC_BASE setting is according to the following queue index
 801 *  BK_QUEUE       ===>                        0
 802 *  BE_QUEUE       ===>                        1
 803 *  VI_QUEUE       ===>                        2
 804 *  VO_QUEUE       ===>                        3
 805 *  HCCA_QUEUE     ===>                        4
 806 *  TXCMD_QUEUE    ===>                        5
 807 *  MGNT_QUEUE     ===>                        6
 808 *  HIGH_QUEUE     ===>                        7
 809 *  BEACON_QUEUE   ===>                        8
 810 *  */
 811static u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA};
 812void rtl8192_tx_enable(struct net_device *dev)
 813{
 814    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 815    u32 i;
 816    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
 817        write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma);
 818
 819    ieee80211_reset_queue(priv->ieee80211);
 820}
 821
 822
 823static void rtl8192_free_rx_ring(struct net_device *dev)
 824{
 825    struct r8192_priv *priv = ieee80211_priv(dev);
 826    int i;
 827
 828    for (i = 0; i < priv->rxringcount; i++) {
 829        struct sk_buff *skb = priv->rx_buf[i];
 830        if (!skb)
 831            continue;
 832
 833        pci_unmap_single(priv->pdev,
 834                *((dma_addr_t *)skb->cb),
 835                priv->rxbuffersize, PCI_DMA_FROMDEVICE);
 836        kfree_skb(skb);
 837    }
 838
 839    pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount,
 840            priv->rx_ring, priv->rx_ring_dma);
 841    priv->rx_ring = NULL;
 842}
 843
 844static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio)
 845{
 846    struct r8192_priv *priv = ieee80211_priv(dev);
 847    struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
 848
 849    while (skb_queue_len(&ring->queue)) {
 850        tx_desc_819x_pci *entry = &ring->desc[ring->idx];
 851        struct sk_buff *skb = __skb_dequeue(&ring->queue);
 852
 853        pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
 854                skb->len, PCI_DMA_TODEVICE);
 855        kfree_skb(skb);
 856        ring->idx = (ring->idx + 1) % ring->entries;
 857    }
 858
 859    pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries,
 860            ring->desc, ring->dma);
 861    ring->desc = NULL;
 862}
 863
 864
 865static void rtl8192_beacon_disable(struct net_device *dev)
 866{
 867        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 868        u32 reg;
 869
 870        reg = read_nic_dword(priv->ieee80211->dev,INTA_MASK);
 871
 872        /* disable Beacon realted interrupt signal */
 873        reg &= ~(IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
 874        write_nic_dword(priv->ieee80211->dev, INTA_MASK, reg);
 875}
 876
 877void rtl8192_rtx_disable(struct net_device *dev)
 878{
 879        u8 cmd;
 880        struct r8192_priv *priv = ieee80211_priv(dev);
 881        int i;
 882
 883        cmd=read_nic_byte(dev,CMDR);
 884//      if(!priv->ieee80211->bSupportRemoteWakeUp) {
 885                write_nic_byte(dev, CMDR, cmd &~ \
 886                                (CR_TE|CR_RE));
 887//      }
 888        force_pci_posting(dev);
 889        mdelay(30);
 890
 891        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
 892                skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
 893        }
 894        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
 895                skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
 896        }
 897
 898
 899        skb_queue_purge(&priv->skb_queue);
 900        return;
 901}
 902
 903static void rtl8192_reset(struct net_device *dev)
 904{
 905    rtl8192_irq_disable(dev);
 906    printk("This is RTL819xP Reset procedure\n");
 907}
 908
 909static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540};
 910inline u16 rtl8192_rate2rate(short rate)
 911{
 912        if (rate >11) return 0;
 913        return rtl_rate[rate];
 914}
 915
 916
 917
 918
 919static void rtl8192_data_hard_stop(struct net_device *dev)
 920{
 921        //FIXME !!
 922        #if 0
 923        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 924        priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
 925        rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
 926        write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
 927        rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
 928        #endif
 929}
 930
 931
 932static void rtl8192_data_hard_resume(struct net_device *dev)
 933{
 934        // FIXME !!
 935        #if 0
 936        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 937        priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
 938        rtl8192_set_mode(dev,EPROM_CMD_CONFIG);
 939        write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
 940        rtl8192_set_mode(dev,EPROM_CMD_NORMAL);
 941        #endif
 942}
 943
 944/* this function TX data frames when the ieee80211 stack requires this.
 945 * It checks also if we need to stop the ieee tx queue, eventually do it
 946 */
 947static void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, int rate)
 948{
 949        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 950        int ret;
 951        //unsigned long flags;
 952        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
 953        u8 queue_index = tcb_desc->queue_index;
 954        /* shall not be referred by command packet */
 955        assert(queue_index != TXCMD_QUEUE);
 956
 957        //spin_lock_irqsave(&priv->tx_lock,flags);
 958
 959        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
 960#if 0
 961        tcb_desc->RATRIndex = 7;
 962        tcb_desc->bTxDisableRateFallBack = 1;
 963        tcb_desc->bTxUseDriverAssingedRate = 1;
 964        tcb_desc->bTxEnableFwCalcDur = 1;
 965#endif
 966        skb_push(skb, priv->ieee80211->tx_headroom);
 967        ret = rtl8192_tx(dev, skb);
 968        if(ret != 0) {
 969                kfree_skb(skb);
 970        };
 971
 972//
 973        if(queue_index!=MGNT_QUEUE) {
 974        priv->ieee80211->stats.tx_bytes+=(skb->len - priv->ieee80211->tx_headroom);
 975        priv->ieee80211->stats.tx_packets++;
 976        }
 977
 978        //spin_unlock_irqrestore(&priv->tx_lock,flags);
 979
 980//      return ret;
 981        return;
 982}
 983
 984/* This is a rough attempt to TX a frame
 985 * This is called by the ieee 80211 stack to TX management frames.
 986 * If the ring is full packet are dropped (for data frame the queue
 987 * is stopped before this can happen).
 988 */
 989static int rtl8192_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
 990{
 991        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
 992
 993
 994        int ret;
 995        //unsigned long flags;
 996        cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
 997        u8 queue_index = tcb_desc->queue_index;
 998
 999
1000        //spin_lock_irqsave(&priv->tx_lock,flags);
1001
1002        memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
1003        if(queue_index == TXCMD_QUEUE) {
1004        //      skb_push(skb, USB_HWDESC_HEADER_LEN);
1005                rtl819xE_tx_cmd(dev, skb);
1006                ret = 0;
1007                //spin_unlock_irqrestore(&priv->tx_lock,flags);
1008                return ret;
1009        } else {
1010        //      RT_TRACE(COMP_SEND, "To send management packet\n");
1011                tcb_desc->RATRIndex = 7;
1012                tcb_desc->bTxDisableRateFallBack = 1;
1013                tcb_desc->bTxUseDriverAssingedRate = 1;
1014                tcb_desc->bTxEnableFwCalcDur = 1;
1015                skb_push(skb, priv->ieee80211->tx_headroom);
1016                ret = rtl8192_tx(dev, skb);
1017                if(ret != 0) {
1018                        kfree_skb(skb);
1019                };
1020        }
1021
1022//      priv->ieee80211->stats.tx_bytes+=skb->len;
1023//      priv->ieee80211->stats.tx_packets++;
1024
1025        //spin_unlock_irqrestore(&priv->tx_lock,flags);
1026
1027        return ret;
1028
1029}
1030
1031
1032void rtl8192_try_wake_queue(struct net_device *dev, int pri);
1033
1034static void rtl8192_tx_isr(struct net_device *dev, int prio)
1035{
1036    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1037
1038    struct rtl8192_tx_ring *ring = &priv->tx_ring[prio];
1039
1040    while (skb_queue_len(&ring->queue)) {
1041        tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1042        struct sk_buff *skb;
1043
1044        /* beacon packet will only use the first descriptor defautly,
1045         * and the OWN may not be cleared by the hardware
1046         * */
1047        if(prio != BEACON_QUEUE) {
1048            if(entry->OWN)
1049                return;
1050            ring->idx = (ring->idx + 1) % ring->entries;
1051        }
1052
1053        skb = __skb_dequeue(&ring->queue);
1054        pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1055                skb->len, PCI_DMA_TODEVICE);
1056
1057        kfree_skb(skb);
1058    }
1059    if (prio == MGNT_QUEUE){
1060        if (priv->ieee80211->ack_tx_to_ieee){
1061            if (rtl8192_is_tx_queue_empty(dev)){
1062                priv->ieee80211->ack_tx_to_ieee = 0;
1063                ieee80211_ps_tx_ack(priv->ieee80211, 1);
1064            }
1065        }
1066    }
1067
1068    if(prio != BEACON_QUEUE) {
1069        /* try to deal with the pending packets  */
1070        tasklet_schedule(&priv->irq_tx_tasklet);
1071    }
1072
1073}
1074
1075static void rtl8192_stop_beacon(struct net_device *dev)
1076{
1077        //rtl8192_beacon_disable(dev);
1078}
1079
1080static void rtl8192_config_rate(struct net_device* dev, u16* rate_config)
1081{
1082         struct r8192_priv *priv = ieee80211_priv(dev);
1083         struct ieee80211_network *net;
1084         u8 i=0, basic_rate = 0;
1085         net = & priv->ieee80211->current_network;
1086
1087         for (i=0; i<net->rates_len; i++)
1088         {
1089                 basic_rate = net->rates[i]&0x7f;
1090                 switch(basic_rate)
1091                 {
1092                         case MGN_1M:   *rate_config |= RRSR_1M;        break;
1093                         case MGN_2M:   *rate_config |= RRSR_2M;        break;
1094                         case MGN_5_5M: *rate_config |= RRSR_5_5M;      break;
1095                         case MGN_11M:  *rate_config |= RRSR_11M;       break;
1096                         case MGN_6M:   *rate_config |= RRSR_6M;        break;
1097                         case MGN_9M:   *rate_config |= RRSR_9M;        break;
1098                         case MGN_12M:  *rate_config |= RRSR_12M;       break;
1099                         case MGN_18M:  *rate_config |= RRSR_18M;       break;
1100                         case MGN_24M:  *rate_config |= RRSR_24M;       break;
1101                         case MGN_36M:  *rate_config |= RRSR_36M;       break;
1102                         case MGN_48M:  *rate_config |= RRSR_48M;       break;
1103                         case MGN_54M:  *rate_config |= RRSR_54M;       break;
1104                 }
1105         }
1106         for (i=0; i<net->rates_ex_len; i++)
1107         {
1108                 basic_rate = net->rates_ex[i]&0x7f;
1109                 switch(basic_rate)
1110                 {
1111                         case MGN_1M:   *rate_config |= RRSR_1M;        break;
1112                         case MGN_2M:   *rate_config |= RRSR_2M;        break;
1113                         case MGN_5_5M: *rate_config |= RRSR_5_5M;      break;
1114                         case MGN_11M:  *rate_config |= RRSR_11M;       break;
1115                         case MGN_6M:   *rate_config |= RRSR_6M;        break;
1116                         case MGN_9M:   *rate_config |= RRSR_9M;        break;
1117                         case MGN_12M:  *rate_config |= RRSR_12M;       break;
1118                         case MGN_18M:  *rate_config |= RRSR_18M;       break;
1119                         case MGN_24M:  *rate_config |= RRSR_24M;       break;
1120                         case MGN_36M:  *rate_config |= RRSR_36M;       break;
1121                         case MGN_48M:  *rate_config |= RRSR_48M;       break;
1122                         case MGN_54M:  *rate_config |= RRSR_54M;       break;
1123                 }
1124         }
1125}
1126
1127
1128#define SHORT_SLOT_TIME 9
1129#define NON_SHORT_SLOT_TIME 20
1130
1131static void rtl8192_update_cap(struct net_device* dev, u16 cap)
1132{
1133        u32 tmp = 0;
1134        struct r8192_priv *priv = ieee80211_priv(dev);
1135        struct ieee80211_network *net = &priv->ieee80211->current_network;
1136        priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE;
1137        tmp = priv->basic_rate;
1138        if (priv->short_preamble)
1139                tmp |= BRSR_AckShortPmb;
1140        write_nic_dword(dev, RRSR, tmp);
1141
1142        if (net->mode & (IEEE_G|IEEE_N_24G))
1143        {
1144                u8 slot_time = 0;
1145                if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime))
1146                {//short slot time
1147                        slot_time = SHORT_SLOT_TIME;
1148                }
1149                else //long slot time
1150                        slot_time = NON_SHORT_SLOT_TIME;
1151                priv->slot_time = slot_time;
1152                write_nic_byte(dev, SLOT_TIME, slot_time);
1153        }
1154
1155}
1156
1157static void rtl8192_net_update(struct net_device *dev)
1158{
1159
1160        struct r8192_priv *priv = ieee80211_priv(dev);
1161        struct ieee80211_network *net;
1162        u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf;
1163        u16 rate_config = 0;
1164        net = &priv->ieee80211->current_network;
1165        //update Basic rate: RR, BRSR
1166        rtl8192_config_rate(dev, &rate_config);
1167        // 2007.01.16, by Emily
1168        // Select RRSR (in Legacy-OFDM and CCK)
1169        // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
1170        // We do not use other rates.
1171         priv->basic_rate = rate_config &= 0x15f;
1172        //BSSID
1173        write_nic_dword(dev,BSSIDR,((u32*)net->bssid)[0]);
1174        write_nic_word(dev,BSSIDR+4,((u16*)net->bssid)[2]);
1175#if 0
1176        //MSR
1177        rtl8192_update_msr(dev);
1178#endif
1179
1180
1181//      rtl8192_update_cap(dev, net->capability);
1182        if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1183        {
1184                write_nic_word(dev, ATIMWND, 2);
1185                write_nic_word(dev, BCN_DMATIME, 256);
1186                write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
1187        //      write_nic_word(dev, BcnIntTime, 100);
1188        //BIT15 of BCN_DRV_EARLY_INT will indicate whether software beacon or hw beacon is applied.
1189                write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
1190                write_nic_byte(dev, BCN_ERR_THRESH, 100);
1191
1192                BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT);
1193        // TODO: BcnIFS may required to be changed on ASIC
1194                BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
1195
1196                write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
1197        }
1198
1199
1200}
1201
1202void rtl819xE_tx_cmd(struct net_device *dev, struct sk_buff *skb)
1203{
1204    struct r8192_priv *priv = ieee80211_priv(dev);
1205    struct rtl8192_tx_ring *ring;
1206    tx_desc_819x_pci *entry;
1207    unsigned int idx;
1208    dma_addr_t mapping;
1209    cb_desc *tcb_desc;
1210    unsigned long flags;
1211
1212    ring = &priv->tx_ring[TXCMD_QUEUE];
1213    mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1214
1215    spin_lock_irqsave(&priv->irq_th_lock,flags);
1216    idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1217    entry = &ring->desc[idx];
1218
1219    tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1220    memset(entry,0,12);
1221    entry->LINIP = tcb_desc->bLastIniPkt;
1222    entry->FirstSeg = 1;//first segment
1223    entry->LastSeg = 1; //last segment
1224    if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) {
1225        entry->CmdInit = DESC_PACKET_TYPE_INIT;
1226    } else {
1227        entry->CmdInit = DESC_PACKET_TYPE_NORMAL;
1228        entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
1229        entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset);
1230        entry->QueueSelect = QSLT_CMD;
1231        entry->TxFWInfoSize = 0x08;
1232        entry->RATid = (u8)DESC_PACKET_TYPE_INIT;
1233    }
1234    entry->TxBufferSize = skb->len;
1235    entry->TxBuffAddr = cpu_to_le32(mapping);
1236    entry->OWN = 1;
1237
1238#ifdef JOHN_DUMP_TXDESC
1239    {       int i;
1240        tx_desc_819x_pci *entry1 =  &ring->desc[0];
1241        unsigned int *ptr= (unsigned int *)entry1;
1242        printk("<Tx descriptor>:\n");
1243        for (i = 0; i < 8; i++)
1244            printk("%8x ", ptr[i]);
1245        printk("\n");
1246    }
1247#endif
1248    __skb_queue_tail(&ring->queue, skb);
1249    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1250
1251    write_nic_byte(dev, TPPoll, TPPoll_CQ);
1252
1253    return;
1254}
1255
1256/*
1257 * Mapping Software/Hardware descriptor queue id to "Queue Select Field"
1258 * in TxFwInfo data structure
1259 * 2006.10.30 by Emily
1260 *
1261 * \param QUEUEID       Software Queue
1262*/
1263static u8 MapHwQueueToFirmwareQueue(u8 QueueID)
1264{
1265        u8 QueueSelect = 0x0;       //defualt set to
1266
1267        switch(QueueID) {
1268                case BE_QUEUE:
1269                        QueueSelect = QSLT_BE;  //or QSelect = pTcb->priority;
1270                        break;
1271
1272                case BK_QUEUE:
1273                        QueueSelect = QSLT_BK;  //or QSelect = pTcb->priority;
1274                        break;
1275
1276                case VO_QUEUE:
1277                        QueueSelect = QSLT_VO;  //or QSelect = pTcb->priority;
1278                        break;
1279
1280                case VI_QUEUE:
1281                        QueueSelect = QSLT_VI;  //or QSelect = pTcb->priority;
1282                        break;
1283                case MGNT_QUEUE:
1284                        QueueSelect = QSLT_MGNT;
1285                        break;
1286
1287                case BEACON_QUEUE:
1288                        QueueSelect = QSLT_BEACON;
1289                        break;
1290
1291                        // TODO: 2006.10.30 mark other queue selection until we verify it is OK
1292                        // TODO: Remove Assertions
1293//#if (RTL819X_FPGA_VER & RTL819X_FPGA_GUANGAN_070502)
1294                case TXCMD_QUEUE:
1295                        QueueSelect = QSLT_CMD;
1296                        break;
1297//#endif
1298                case HIGH_QUEUE:
1299                        //QueueSelect = QSLT_HIGH;
1300                        //break;
1301
1302                default:
1303                        RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection: %d \n", QueueID);
1304                        break;
1305        }
1306        return QueueSelect;
1307}
1308
1309static u8 MRateToHwRate8190Pci(u8 rate)
1310{
1311        u8  ret = DESC90_RATE1M;
1312
1313        switch(rate) {
1314                case MGN_1M:    ret = DESC90_RATE1M;            break;
1315                case MGN_2M:    ret = DESC90_RATE2M;            break;
1316                case MGN_5_5M:  ret = DESC90_RATE5_5M;  break;
1317                case MGN_11M:   ret = DESC90_RATE11M;   break;
1318                case MGN_6M:    ret = DESC90_RATE6M;            break;
1319                case MGN_9M:    ret = DESC90_RATE9M;            break;
1320                case MGN_12M:   ret = DESC90_RATE12M;   break;
1321                case MGN_18M:   ret = DESC90_RATE18M;   break;
1322                case MGN_24M:   ret = DESC90_RATE24M;   break;
1323                case MGN_36M:   ret = DESC90_RATE36M;   break;
1324                case MGN_48M:   ret = DESC90_RATE48M;   break;
1325                case MGN_54M:   ret = DESC90_RATE54M;   break;
1326
1327                // HT rate since here
1328                case MGN_MCS0:  ret = DESC90_RATEMCS0;  break;
1329                case MGN_MCS1:  ret = DESC90_RATEMCS1;  break;
1330                case MGN_MCS2:  ret = DESC90_RATEMCS2;  break;
1331                case MGN_MCS3:  ret = DESC90_RATEMCS3;  break;
1332                case MGN_MCS4:  ret = DESC90_RATEMCS4;  break;
1333                case MGN_MCS5:  ret = DESC90_RATEMCS5;  break;
1334                case MGN_MCS6:  ret = DESC90_RATEMCS6;  break;
1335                case MGN_MCS7:  ret = DESC90_RATEMCS7;  break;
1336                case MGN_MCS8:  ret = DESC90_RATEMCS8;  break;
1337                case MGN_MCS9:  ret = DESC90_RATEMCS9;  break;
1338                case MGN_MCS10: ret = DESC90_RATEMCS10; break;
1339                case MGN_MCS11: ret = DESC90_RATEMCS11; break;
1340                case MGN_MCS12: ret = DESC90_RATEMCS12; break;
1341                case MGN_MCS13: ret = DESC90_RATEMCS13; break;
1342                case MGN_MCS14: ret = DESC90_RATEMCS14; break;
1343                case MGN_MCS15: ret = DESC90_RATEMCS15; break;
1344                case (0x80|0x20): ret = DESC90_RATEMCS32; break;
1345
1346                default:       break;
1347        }
1348        return ret;
1349}
1350
1351
1352static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc)
1353{
1354        u8   tmp_Short;
1355
1356        tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0);
1357
1358        if(TxHT==1 && TxRate != DESC90_RATEMCS15)
1359                tmp_Short = 0;
1360
1361        return tmp_Short;
1362}
1363
1364/*
1365 * The tx procedure is just as following,
1366 * skb->cb will contain all the following information,
1367 * priority, morefrag, rate, &dev.
1368 * */
1369short rtl8192_tx(struct net_device *dev, struct sk_buff* skb)
1370{
1371    struct r8192_priv *priv = ieee80211_priv(dev);
1372    struct rtl8192_tx_ring  *ring;
1373    unsigned long flags;
1374    cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
1375    tx_desc_819x_pci *pdesc = NULL;
1376    TX_FWINFO_8190PCI *pTxFwInfo = NULL;
1377    dma_addr_t mapping;
1378    bool  multi_addr=false,broad_addr=false,uni_addr=false;
1379    u8*   pda_addr = NULL;
1380    int   idx;
1381
1382    mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
1383    /* collect the tx packets statitcs */
1384    pda_addr = ((u8*)skb->data) + sizeof(TX_FWINFO_8190PCI);
1385    if(is_multicast_ether_addr(pda_addr))
1386        multi_addr = true;
1387    else if(is_broadcast_ether_addr(pda_addr))
1388        broad_addr = true;
1389    else
1390        uni_addr = true;
1391
1392    if(uni_addr)
1393        priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1394    else if(multi_addr)
1395        priv->stats.txbytesmulticast +=(u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1396    else
1397        priv->stats.txbytesbroadcast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI);
1398
1399    /* fill tx firmware */
1400    pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data;
1401    memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
1402    pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80)?1:0;
1403    pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate);
1404    pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur;
1405    pTxFwInfo->Short    = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc);
1406
1407    /* Aggregation related */
1408    if(tcb_desc->bAMPDUEnable) {
1409        pTxFwInfo->AllowAggregation = 1;
1410        pTxFwInfo->RxMF = tcb_desc->ampdu_factor;
1411        pTxFwInfo->RxAMD = tcb_desc->ampdu_density;
1412    } else {
1413        pTxFwInfo->AllowAggregation = 0;
1414        pTxFwInfo->RxMF = 0;
1415        pTxFwInfo->RxAMD = 0;
1416    }
1417
1418    //
1419    // Protection mode related
1420    //
1421    pTxFwInfo->RtsEnable =      (tcb_desc->bRTSEnable)?1:0;
1422    pTxFwInfo->CtsEnable =      (tcb_desc->bCTSEnable)?1:0;
1423    pTxFwInfo->RtsSTBC =        (tcb_desc->bRTSSTBC)?1:0;
1424    pTxFwInfo->RtsHT=           (tcb_desc->rts_rate&0x80)?1:0;
1425    pTxFwInfo->RtsRate =                MRateToHwRate8190Pci((u8)tcb_desc->rts_rate);
1426    pTxFwInfo->RtsBandwidth = 0;
1427    pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC;
1428    pTxFwInfo->RtsShort =       (pTxFwInfo->RtsHT==0)?(tcb_desc->bRTSUseShortPreamble?1:0):(tcb_desc->bRTSUseShortGI?1:0);
1429    //
1430    // Set Bandwidth and sub-channel settings.
1431    //
1432    if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40)
1433    {
1434        if(tcb_desc->bPacketBW)
1435        {
1436            pTxFwInfo->TxBandwidth = 1;
1437#ifdef RTL8190P
1438            pTxFwInfo->TxSubCarrier = 3;
1439#else
1440            pTxFwInfo->TxSubCarrier = 0;        //By SD3's Jerry suggestion, use duplicated mode, cosa 04012008
1441#endif
1442        }
1443        else
1444        {
1445            pTxFwInfo->TxBandwidth = 0;
1446            pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC;
1447        }
1448    } else {
1449        pTxFwInfo->TxBandwidth = 0;
1450        pTxFwInfo->TxSubCarrier = 0;
1451    }
1452
1453    if (0)
1454    {
1455            /* 2007/07/25 MH  Copy current TX FW info.*/
1456            memcpy((void*)(&Tmp_TxFwInfo), (void*)(pTxFwInfo), sizeof(TX_FWINFO_8190PCI));
1457            printk("&&&&&&&&&&&&&&&&&&&&&&====>print out fwinf\n");
1458            printk("===>enable fwcacl:%d\n", Tmp_TxFwInfo.EnableCPUDur);
1459            printk("===>RTS STBC:%d\n", Tmp_TxFwInfo.RtsSTBC);
1460            printk("===>RTS Subcarrier:%d\n", Tmp_TxFwInfo.RtsSubcarrier);
1461            printk("===>Allow Aggregation:%d\n", Tmp_TxFwInfo.AllowAggregation);
1462            printk("===>TX HT bit:%d\n", Tmp_TxFwInfo.TxHT);
1463            printk("===>Tx rate:%d\n", Tmp_TxFwInfo.TxRate);
1464            printk("===>Received AMPDU Density:%d\n", Tmp_TxFwInfo.RxAMD);
1465            printk("===>Received MPDU Factor:%d\n", Tmp_TxFwInfo.RxMF);
1466            printk("===>TxBandwidth:%d\n", Tmp_TxFwInfo.TxBandwidth);
1467            printk("===>TxSubCarrier:%d\n", Tmp_TxFwInfo.TxSubCarrier);
1468
1469        printk("<=====**********************out of print\n");
1470
1471    }
1472    spin_lock_irqsave(&priv->irq_th_lock,flags);
1473    ring = &priv->tx_ring[tcb_desc->queue_index];
1474    if (tcb_desc->queue_index != BEACON_QUEUE) {
1475        idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
1476    } else {
1477        idx = 0;
1478    }
1479
1480    pdesc = &ring->desc[idx];
1481    if((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) {
1482            RT_TRACE(COMP_ERR,"No more TX desc@%d, ring->idx = %d,idx = %d,%x", \
1483                            tcb_desc->queue_index,ring->idx, idx,skb->len);
1484            return skb->len;
1485    }
1486
1487    /* fill tx descriptor */
1488    memset((u8*)pdesc,0,12);
1489    /*DWORD 0*/
1490    pdesc->LINIP = 0;
1491    pdesc->CmdInit = 1;
1492    pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; //We must add 8!! Emily
1493    pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI);
1494
1495    /*DWORD 1*/
1496    pdesc->SecCAMID= 0;
1497    pdesc->RATid = tcb_desc->RATRIndex;
1498
1499
1500    pdesc->NoEnc = 1;
1501    pdesc->SecType = 0x0;
1502    if (tcb_desc->bHwSec) {
1503        static u8 tmp =0;
1504        if (!tmp) {
1505            printk("==>================hw sec\n");
1506            tmp = 1;
1507        }
1508        switch (priv->ieee80211->pairwise_key_type) {
1509            case KEY_TYPE_WEP40:
1510            case KEY_TYPE_WEP104:
1511                pdesc->SecType = 0x1;
1512                pdesc->NoEnc = 0;
1513                break;
1514            case KEY_TYPE_TKIP:
1515                pdesc->SecType = 0x2;
1516                pdesc->NoEnc = 0;
1517                break;
1518            case KEY_TYPE_CCMP:
1519                pdesc->SecType = 0x3;
1520                pdesc->NoEnc = 0;
1521                break;
1522            case KEY_TYPE_NA:
1523                pdesc->SecType = 0x0;
1524                pdesc->NoEnc = 1;
1525                break;
1526        }
1527    }
1528
1529    //
1530    // Set Packet ID
1531    //
1532    pdesc->PktId = 0x0;
1533
1534    pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index);
1535    pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI);
1536
1537    pdesc->DISFB = tcb_desc->bTxDisableRateFallBack;
1538    pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate;
1539
1540    pdesc->FirstSeg =1;
1541    pdesc->LastSeg = 1;
1542    pdesc->TxBufferSize = skb->len;
1543
1544    pdesc->TxBuffAddr = cpu_to_le32(mapping);
1545    __skb_queue_tail(&ring->queue, skb);
1546    pdesc->OWN = 1;
1547    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
1548    dev->trans_start = jiffies;
1549    write_nic_word(dev,TPPoll,0x01<<tcb_desc->queue_index);
1550    return 0;
1551}
1552
1553static short rtl8192_alloc_rx_desc_ring(struct net_device *dev)
1554{
1555    struct r8192_priv *priv = ieee80211_priv(dev);
1556    rx_desc_819x_pci *entry = NULL;
1557    int i;
1558
1559    priv->rx_ring = pci_alloc_consistent(priv->pdev,
1560            sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma);
1561
1562    if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1563        RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n");
1564        return -ENOMEM;
1565    }
1566
1567    memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount);
1568    priv->rx_idx = 0;
1569
1570    for (i = 0; i < priv->rxringcount; i++) {
1571        struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize);
1572        dma_addr_t *mapping;
1573        entry = &priv->rx_ring[i];
1574        if (!skb)
1575            return 0;
1576        priv->rx_buf[i] = skb;
1577        mapping = (dma_addr_t *)skb->cb;
1578        *mapping = pci_map_single(priv->pdev, skb->tail,//skb_tail_pointer(skb),
1579                priv->rxbuffersize, PCI_DMA_FROMDEVICE);
1580
1581        entry->BufferAddress = cpu_to_le32(*mapping);
1582
1583        entry->Length = priv->rxbuffersize;
1584        entry->OWN = 1;
1585    }
1586
1587    entry->EOR = 1;
1588    return 0;
1589}
1590
1591static int rtl8192_alloc_tx_desc_ring(struct net_device *dev,
1592        unsigned int prio, unsigned int entries)
1593{
1594    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
1595    tx_desc_819x_pci *ring;
1596    dma_addr_t dma;
1597    int i;
1598
1599    ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
1600    if (!ring || (unsigned long)ring & 0xFF) {
1601        RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio);
1602        return -ENOMEM;
1603    }
1604
1605    memset(ring, 0, sizeof(*ring)*entries);
1606    priv->tx_ring[prio].desc = ring;
1607    priv->tx_ring[prio].dma = dma;
1608    priv->tx_ring[prio].idx = 0;
1609    priv->tx_ring[prio].entries = entries;
1610    skb_queue_head_init(&priv->tx_ring[prio].queue);
1611
1612    for (i = 0; i < entries; i++)
1613        ring[i].NextDescAddress =
1614            cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1615
1616    return 0;
1617}
1618
1619
1620static short rtl8192_pci_initdescring(struct net_device *dev)
1621{
1622    u32 ret;
1623    int i;
1624    struct r8192_priv *priv = ieee80211_priv(dev);
1625
1626    ret = rtl8192_alloc_rx_desc_ring(dev);
1627    if (ret) {
1628        return ret;
1629    }
1630
1631
1632    /* general process for other queue */
1633    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1634        if ((ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount)))
1635            goto err_free_rings;
1636    }
1637
1638#if 0
1639    /* specific process for hardware beacon process */
1640    if ((ret = rtl8192_alloc_tx_desc_ring(dev, MAX_TX_QUEUE_COUNT - 1, 2)))
1641        goto err_free_rings;
1642#endif
1643
1644    return 0;
1645
1646err_free_rings:
1647    rtl8192_free_rx_ring(dev);
1648    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++)
1649        if (priv->tx_ring[i].desc)
1650            rtl8192_free_tx_ring(dev, i);
1651    return 1;
1652}
1653
1654static void rtl8192_pci_resetdescring(struct net_device *dev)
1655{
1656    struct r8192_priv *priv = ieee80211_priv(dev);
1657    int i;
1658
1659    /* force the rx_idx to the first one */
1660    if(priv->rx_ring) {
1661        rx_desc_819x_pci *entry = NULL;
1662        for (i = 0; i < priv->rxringcount; i++) {
1663            entry = &priv->rx_ring[i];
1664            entry->OWN = 1;
1665        }
1666        priv->rx_idx = 0;
1667    }
1668
1669    /* after reset, release previous pending packet, and force the
1670     * tx idx to the first one */
1671    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
1672        if (priv->tx_ring[i].desc) {
1673            struct rtl8192_tx_ring *ring = &priv->tx_ring[i];
1674
1675            while (skb_queue_len(&ring->queue)) {
1676                tx_desc_819x_pci *entry = &ring->desc[ring->idx];
1677                struct sk_buff *skb = __skb_dequeue(&ring->queue);
1678
1679                pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr),
1680                        skb->len, PCI_DMA_TODEVICE);
1681                kfree_skb(skb);
1682                ring->idx = (ring->idx + 1) % ring->entries;
1683            }
1684            ring->idx = 0;
1685        }
1686    }
1687}
1688
1689#if 1
1690extern void rtl8192_update_ratr_table(struct net_device* dev);
1691static void rtl8192_link_change(struct net_device *dev)
1692{
1693//      int i;
1694
1695        struct r8192_priv *priv = ieee80211_priv(dev);
1696        struct ieee80211_device* ieee = priv->ieee80211;
1697        //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
1698        if (ieee->state == IEEE80211_LINKED)
1699        {
1700                rtl8192_net_update(dev);
1701                rtl8192_update_ratr_table(dev);
1702#if 1
1703                //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08
1704                if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
1705                EnableHWSecurityConfig8192(dev);
1706#endif
1707        }
1708        else
1709        {
1710                write_nic_byte(dev, 0x173, 0);
1711        }
1712        /*update timing params*/
1713        //rtl8192_set_chan(dev, priv->chan);
1714        //MSR
1715        rtl8192_update_msr(dev);
1716
1717        // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have
1718        //      // To set CBSSID bit when link with any AP or STA.
1719        if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1720        {
1721                u32 reg = 0;
1722                reg = read_nic_dword(dev, RCR);
1723                if (priv->ieee80211->state == IEEE80211_LINKED)
1724                        priv->ReceiveConfig = reg |= RCR_CBSSID;
1725                else
1726                        priv->ReceiveConfig = reg &= ~RCR_CBSSID;
1727                write_nic_dword(dev, RCR, reg);
1728        }
1729}
1730#endif
1731
1732
1733static struct ieee80211_qos_parameters def_qos_parameters = {
1734        {3,3,3,3},/* cw_min */
1735        {7,7,7,7},/* cw_max */
1736        {2,2,2,2},/* aifs */
1737        {0,0,0,0},/* flags */
1738        {0,0,0,0} /* tx_op_limit */
1739};
1740
1741static void rtl8192_update_beacon(struct work_struct * work)
1742{
1743        struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
1744        struct net_device *dev = priv->ieee80211->dev;
1745        struct ieee80211_device* ieee = priv->ieee80211;
1746        struct ieee80211_network* net = &ieee->current_network;
1747
1748        if (ieee->pHTInfo->bCurrentHTSupport)
1749                HTUpdateSelfAndPeerSetting(ieee, net);
1750        ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
1751        rtl8192_update_cap(dev, net->capability);
1752}
1753/*
1754* background support to run QoS activate functionality
1755*/
1756static int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
1757static void rtl8192_qos_activate(struct work_struct * work)
1758{
1759        struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
1760        struct net_device *dev = priv->ieee80211->dev;
1761        struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1762        u8 mode = priv->ieee80211->current_network.mode;
1763//        u32 size = sizeof(struct ieee80211_qos_parameters);
1764        u8  u1bAIFS;
1765        u32 u4bAcParam;
1766        int i;
1767
1768        mutex_lock(&priv->mutex);
1769        if(priv->ieee80211->state != IEEE80211_LINKED)
1770                goto success;
1771        RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
1772        /* It better set slot time at first */
1773        /* For we just support b/g mode at present, let the slot time at 9/20 selection */
1774        /* update the ac parameter to related registers */
1775        for(i = 0; i <  QOS_QUEUE_NUM; i++) {
1776                //Mode G/A: slotTimeTimer = 9; Mode B: 20
1777                u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1778                u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1779                                (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
1780                                (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
1781                                ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1782                printk("===>u4bAcParam:%x, ", u4bAcParam);
1783                write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1784                //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
1785        }
1786
1787success:
1788        mutex_unlock(&priv->mutex);
1789}
1790
1791static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
1792                int active_network,
1793                struct ieee80211_network *network)
1794{
1795        int ret = 0;
1796        u32 size = sizeof(struct ieee80211_qos_parameters);
1797
1798        if(priv->ieee80211->state !=IEEE80211_LINKED)
1799                return ret;
1800
1801        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1802                return ret;
1803
1804        if (network->flags & NETWORK_HAS_QOS_MASK) {
1805                if (active_network &&
1806                                (network->flags & NETWORK_HAS_QOS_PARAMETERS))
1807                        network->qos_data.active = network->qos_data.supported;
1808
1809                if ((network->qos_data.active == 1) && (active_network == 1) &&
1810                                (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
1811                                (network->qos_data.old_param_count !=
1812                                 network->qos_data.param_count)) {
1813                        network->qos_data.old_param_count =
1814                                network->qos_data.param_count;
1815                        queue_work(priv->priv_wq, &priv->qos_activate);
1816                        RT_TRACE (COMP_QOS, "QoS parameters change call "
1817                                        "qos_activate\n");
1818                }
1819        } else {
1820                memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
1821                       &def_qos_parameters, size);
1822
1823                if ((network->qos_data.active == 1) && (active_network == 1)) {
1824                        queue_work(priv->priv_wq, &priv->qos_activate);
1825                        RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
1826                }
1827                network->qos_data.active = 0;
1828                network->qos_data.supported = 0;
1829        }
1830
1831        return 0;
1832}
1833
1834/* handle manage frame frame beacon and probe response */
1835static int rtl8192_handle_beacon(struct net_device * dev,
1836                              struct ieee80211_beacon * beacon,
1837                              struct ieee80211_network * network)
1838{
1839        struct r8192_priv *priv = ieee80211_priv(dev);
1840
1841        rtl8192_qos_handle_probe_response(priv,1,network);
1842
1843        queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
1844        return 0;
1845
1846}
1847
1848/*
1849* handling the beaconing responses. if we get different QoS setting
1850* off the network from the associated setting, adjust the QoS
1851* setting
1852*/
1853static int rtl8192_qos_association_resp(struct r8192_priv *priv,
1854                                    struct ieee80211_network *network)
1855{
1856        int ret = 0;
1857        unsigned long flags;
1858        u32 size = sizeof(struct ieee80211_qos_parameters);
1859        int set_qos_param = 0;
1860
1861        if ((priv == NULL) || (network == NULL))
1862                return ret;
1863
1864        if(priv->ieee80211->state !=IEEE80211_LINKED)
1865                return ret;
1866
1867        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
1868                return ret;
1869
1870        spin_lock_irqsave(&priv->ieee80211->lock, flags);
1871        if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
1872                memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
1873                         &network->qos_data.parameters,\
1874                        sizeof(struct ieee80211_qos_parameters));
1875                priv->ieee80211->current_network.qos_data.active = 1;
1876#if 0
1877                if((priv->ieee80211->current_network.qos_data.param_count != \
1878                                        network->qos_data.param_count))
1879#endif
1880                 {
1881                        set_qos_param = 1;
1882                        /* update qos parameter for current network */
1883                        priv->ieee80211->current_network.qos_data.old_param_count = \
1884                                 priv->ieee80211->current_network.qos_data.param_count;
1885                        priv->ieee80211->current_network.qos_data.param_count = \
1886                                 network->qos_data.param_count;
1887                }
1888        } else {
1889                memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
1890                       &def_qos_parameters, size);
1891                priv->ieee80211->current_network.qos_data.active = 0;
1892                priv->ieee80211->current_network.qos_data.supported = 0;
1893                set_qos_param = 1;
1894        }
1895
1896        spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
1897
1898        RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
1899        if (set_qos_param == 1)
1900                queue_work(priv->priv_wq, &priv->qos_activate);
1901
1902        return ret;
1903}
1904
1905
1906static int rtl8192_handle_assoc_response(struct net_device *dev,
1907                                     struct ieee80211_assoc_response_frame *resp,
1908                                     struct ieee80211_network *network)
1909{
1910        struct r8192_priv *priv = ieee80211_priv(dev);
1911        rtl8192_qos_association_resp(priv, network);
1912        return 0;
1913}
1914
1915
1916//updateRATRTabel for MCS only. Basic rate is not implement.
1917void rtl8192_update_ratr_table(struct net_device* dev)
1918        //      POCTET_STRING   posLegacyRate,
1919        //      u8*                     pMcsRate)
1920        //      PRT_WLAN_STA    pEntry)
1921{
1922        struct r8192_priv* priv = ieee80211_priv(dev);
1923        struct ieee80211_device* ieee = priv->ieee80211;
1924        u8* pMcsRate = ieee->dot11HTOperationalRateSet;
1925        //struct ieee80211_network *net = &ieee->current_network;
1926        u32 ratr_value = 0;
1927        u8 rate_index = 0;
1928
1929        rtl8192_config_rate(dev, (u16*)(&ratr_value));
1930        ratr_value |= (*(u16*)(pMcsRate)) << 12;
1931//      switch (net->mode)
1932        switch (ieee->mode)
1933        {
1934                case IEEE_A:
1935                        ratr_value &= 0x00000FF0;
1936                        break;
1937                case IEEE_B:
1938                        ratr_value &= 0x0000000F;
1939                        break;
1940                case IEEE_G:
1941                        ratr_value &= 0x00000FF7;
1942                        break;
1943                case IEEE_N_24G:
1944                case IEEE_N_5G:
1945                        if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
1946                                ratr_value &= 0x0007F007;
1947                        else{
1948                                if (priv->rf_type == RF_1T2R)
1949                                        ratr_value &= 0x000FF007;
1950                                else
1951                                        ratr_value &= 0x0F81F007;
1952                        }
1953                        break;
1954                default:
1955                        break;
1956        }
1957        ratr_value &= 0x0FFFFFFF;
1958        if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
1959                ratr_value |= 0x80000000;
1960        }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
1961                ratr_value |= 0x80000000;
1962        }
1963        write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
1964        write_nic_byte(dev, UFWP, 1);
1965}
1966
1967static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
1968static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
1969static bool GetNmodeSupportBySecCfg8190Pci(struct net_device*dev)
1970{
1971#if 1
1972        struct r8192_priv* priv = ieee80211_priv(dev);
1973        struct ieee80211_device* ieee = priv->ieee80211;
1974        int wpa_ie_len= ieee->wpa_ie_len;
1975        struct ieee80211_crypt_data* crypt;
1976        int encrypt;
1977
1978        crypt = ieee->crypt[ieee->tx_keyidx];
1979        encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
1980
1981        /* simply judge  */
1982        if(encrypt && (wpa_ie_len == 0)) {
1983                /* wep encryption, no N mode setting */
1984                return false;
1985//      } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
1986        } else if((wpa_ie_len != 0)) {
1987                /* parse pairwise key type */
1988                //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
1989                if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
1990                        return true;
1991                else
1992                        return false;
1993        } else {
1994                //RT_TRACE(COMP_ERR,"In %s The GroupEncAlgorithm is [4]\n",__FUNCTION__ );
1995                return true;
1996        }
1997
1998#if 0
1999        //In here we discuss with SD4 David. He think we still can send TKIP in broadcast group key in MCS rate.
2000        //We can't force in G mode if Pairwie key is AES and group key is TKIP
2001        if((pSecInfo->GroupEncAlgorithm == WEP104_Encryption) || (pSecInfo->GroupEncAlgorithm == WEP40_Encryption)  ||
2002           (pSecInfo->PairwiseEncAlgorithm == WEP104_Encryption) ||
2003           (pSecInfo->PairwiseEncAlgorithm == WEP40_Encryption) || (pSecInfo->PairwiseEncAlgorithm == TKIP_Encryption))
2004        {
2005                return  false;
2006        }
2007        else
2008                return true;
2009#endif
2010        return true;
2011#endif
2012}
2013
2014static void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2015{
2016        struct ieee80211_device* ieee = priv->ieee80211;
2017        //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2018        if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2019        {
2020                memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2021                //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2022                //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2023        }
2024        else
2025                memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2026        return;
2027}
2028
2029static u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2030{
2031        struct r8192_priv *priv = ieee80211_priv(dev);
2032        u8 ret = 0;
2033        switch(priv->rf_chip)
2034        {
2035                case RF_8225:
2036                case RF_8256:
2037                case RF_PSEUDO_11N:
2038                        ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2039                        break;
2040                case RF_8258:
2041                        ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2042                        break;
2043                default:
2044                        ret = WIRELESS_MODE_B;
2045                        break;
2046        }
2047        return ret;
2048}
2049
2050static void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2051{
2052        struct r8192_priv *priv = ieee80211_priv(dev);
2053        u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2054
2055#if 1
2056        if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2057        {
2058                if(bSupportMode & WIRELESS_MODE_N_24G)
2059                {
2060                        wireless_mode = WIRELESS_MODE_N_24G;
2061                }
2062                else if(bSupportMode & WIRELESS_MODE_N_5G)
2063                {
2064                        wireless_mode = WIRELESS_MODE_N_5G;
2065                }
2066                else if((bSupportMode & WIRELESS_MODE_A))
2067                {
2068                        wireless_mode = WIRELESS_MODE_A;
2069                }
2070                else if((bSupportMode & WIRELESS_MODE_G))
2071                {
2072                        wireless_mode = WIRELESS_MODE_G;
2073                }
2074                else if((bSupportMode & WIRELESS_MODE_B))
2075                {
2076                        wireless_mode = WIRELESS_MODE_B;
2077                }
2078                else{
2079                        RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2080                        wireless_mode = WIRELESS_MODE_B;
2081                }
2082        }
2083#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we shoud wait for FPGA
2084        ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2085#endif
2086        priv->ieee80211->mode = wireless_mode;
2087
2088        if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
2089                priv->ieee80211->pHTInfo->bEnableHT = 1;
2090        else
2091                priv->ieee80211->pHTInfo->bEnableHT = 0;
2092        RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2093        rtl8192_refresh_supportrate(priv);
2094#endif
2095
2096}
2097//init priv variables here
2098
2099static bool GetHalfNmodeSupportByAPs819xPci(struct net_device* dev)
2100{
2101        bool                    Reval;
2102        struct r8192_priv* priv = ieee80211_priv(dev);
2103        struct ieee80211_device* ieee = priv->ieee80211;
2104
2105        if(ieee->bHalfWirelessN24GMode == true)
2106                Reval = true;
2107        else
2108                Reval =  false;
2109
2110        return Reval;
2111}
2112
2113short rtl8192_is_tx_queue_empty(struct net_device *dev)
2114{
2115        int i=0;
2116        struct r8192_priv *priv = ieee80211_priv(dev);
2117        for (i=0; i<=MGNT_QUEUE; i++)
2118        {
2119                if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) )
2120                        continue;
2121                if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){
2122                        printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue));
2123                        return 0;
2124                }
2125        }
2126        return 1;
2127}
2128static void rtl8192_hw_sleep_down(struct net_device *dev)
2129{
2130        RT_TRACE(COMP_POWER, "%s()============>come to sleep down\n", __FUNCTION__);
2131        MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
2132}
2133static void rtl8192_hw_sleep_wq (struct work_struct *work)
2134{
2135//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2136//      struct ieee80211_device * ieee = (struct ieee80211_device*)
2137//                                             container_of(work, struct ieee80211_device, watch_dog_wq);
2138        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2139        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
2140        struct net_device *dev = ieee->dev;
2141        //printk("=========>%s()\n", __FUNCTION__);
2142        rtl8192_hw_sleep_down(dev);
2143}
2144//      printk("dev is %d\n",dev);
2145//      printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
2146static void rtl8192_hw_wakeup(struct net_device* dev)
2147{
2148//      u32 flags = 0;
2149
2150//      spin_lock_irqsave(&priv->ps_lock,flags);
2151        RT_TRACE(COMP_POWER, "%s()============>come to wake up\n", __FUNCTION__);
2152        MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
2153        //FIXME: will we send package stored while nic is sleep?
2154//      spin_unlock_irqrestore(&priv->ps_lock,flags);
2155}
2156void rtl8192_hw_wakeup_wq (struct work_struct *work)
2157{
2158//      struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
2159//      struct ieee80211_device * ieee = (struct ieee80211_device*)
2160//                                             container_of(work, struct ieee80211_device, watch_dog_wq);
2161        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2162        struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
2163        struct net_device *dev = ieee->dev;
2164        rtl8192_hw_wakeup(dev);
2165
2166}
2167
2168#define MIN_SLEEP_TIME 50
2169#define MAX_SLEEP_TIME 10000
2170static void rtl8192_hw_to_sleep(struct net_device *dev, u32 th, u32 tl)
2171{
2172
2173        struct r8192_priv *priv = ieee80211_priv(dev);
2174
2175        u32 rb = jiffies;
2176        unsigned long flags;
2177
2178        spin_lock_irqsave(&priv->ps_lock,flags);
2179
2180        /* Writing HW register with 0 equals to disable
2181         * the timer, that is not really what we want
2182         */
2183        tl -= MSECS(4+16+7);
2184
2185        //if(tl == 0) tl = 1;
2186
2187        /* FIXME HACK FIXME HACK */
2188//      force_pci_posting(dev);
2189        //mdelay(1);
2190
2191//      rb = read_nic_dword(dev, TSFTR);
2192
2193        /* If the interval in witch we are requested to sleep is too
2194         * short then give up and remain awake
2195         */
2196        if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
2197                ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
2198                spin_unlock_irqrestore(&priv->ps_lock,flags);
2199                printk("too short to sleep\n");
2200                return;
2201        }
2202
2203//      write_nic_dword(dev, TimerInt, tl);
2204//      rb = read_nic_dword(dev, TSFTR);
2205        {
2206                u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
2207        //      if (tl<rb)
2208                queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
2209        }
2210        /* if we suspect the TimerInt is gone beyond tl
2211         * while setting it, then give up
2212         */
2213#if 1
2214        if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
2215                ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
2216                printk("========>too long to sleep:%x, %x, %lx\n", tl, rb,  MSECS(MAX_SLEEP_TIME));
2217                spin_unlock_irqrestore(&priv->ps_lock,flags);
2218                return;
2219        }
2220#endif
2221//      if(priv->rf_sleep)
2222//              priv->rf_sleep(dev);
2223
2224        //printk("<=========%s()\n", __FUNCTION__);
2225        queue_delayed_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq,0);
2226        spin_unlock_irqrestore(&priv->ps_lock,flags);
2227}
2228static void rtl8192_init_priv_variable(struct net_device* dev)
2229{
2230        struct r8192_priv *priv = ieee80211_priv(dev);
2231        u8 i;
2232        priv->being_init_adapter = false;
2233        priv->txbuffsize = 1600;//1024;
2234        priv->txfwbuffersize = 4096;
2235        priv->txringcount = 64;//32;
2236        //priv->txbeaconcount = priv->txringcount;
2237        priv->txbeaconcount = 2;
2238        priv->rxbuffersize = 9100;//2048;//1024;
2239        priv->rxringcount = MAX_RX_COUNT;//64;
2240        priv->irq_enabled=0;
2241        priv->card_8192 = NIC_8192E;
2242        priv->rx_skb_complete = 1;
2243        priv->chan = 1; //set to channel 1
2244        priv->RegWirelessMode = WIRELESS_MODE_AUTO;
2245        priv->RegChannelPlan = 0xf;
2246        priv->nrxAMPDU_size = 0;
2247        priv->nrxAMPDU_aggr_num = 0;
2248        priv->last_rxdesc_tsf_high = 0;
2249        priv->last_rxdesc_tsf_low = 0;
2250        priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2251        priv->ieee80211->iw_mode = IW_MODE_INFRA;
2252        priv->ieee80211->ieee_up=0;
2253        priv->retry_rts = DEFAULT_RETRY_RTS;
2254        priv->retry_data = DEFAULT_RETRY_DATA;
2255        priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2256        priv->ieee80211->rate = 110; //11 mbps
2257        priv->ieee80211->short_slot = 1;
2258        priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2259        priv->bcck_in_ch14 = false;
2260        priv->bfsync_processing  = false;
2261        priv->CCKPresentAttentuation = 0;
2262        priv->rfa_txpowertrackingindex = 0;
2263        priv->rfc_txpowertrackingindex = 0;
2264        priv->CckPwEnl = 6;
2265        priv->ScanDelay = 50;//for Scan TODO
2266        //added by amy for silent reset
2267        priv->ResetProgress = RESET_TYPE_NORESET;
2268        priv->bForcedSilentReset = 0;
2269        priv->bDisableNormalResetCheck = false;
2270        priv->force_reset = false;
2271        //added by amy for power save
2272        priv->RegRfOff = 0;
2273        priv->ieee80211->RfOffReason = 0;
2274        priv->RFChangeInProgress = false;
2275        priv->bHwRfOffAction = 0;
2276        priv->SetRFPowerStateInProgress = false;
2277        priv->ieee80211->PowerSaveControl.bInactivePs = true;
2278        priv->ieee80211->PowerSaveControl.bIPSModeBackup = false;
2279        //just for debug
2280        priv->txpower_checkcnt = 0;
2281        priv->thermal_readback_index =0;
2282        priv->txpower_tracking_callback_cnt = 0;
2283        priv->ccktxpower_adjustcnt_ch14 = 0;
2284        priv->ccktxpower_adjustcnt_not_ch14 = 0;
2285
2286        priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2287        priv->ieee80211->iw_mode = IW_MODE_INFRA;
2288        priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
2289                IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2290                IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* |
2291                IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //|  //IEEE_SOFTMAC_SINGLE_QUEUE;
2292
2293        priv->ieee80211->active_scan = 1;
2294        priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2295        priv->ieee80211->host_encrypt = 1;
2296        priv->ieee80211->host_decrypt = 1;
2297        //priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2298        //priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2299        priv->ieee80211->start_send_beacons = rtl8192_start_beacon;//+by david 081107
2300        priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon;//+by david 081107
2301        priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2302        priv->ieee80211->set_chan = rtl8192_set_chan;
2303        priv->ieee80211->link_change = rtl8192_link_change;
2304        priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2305        priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2306        priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2307        priv->ieee80211->init_wmmparam_flag = 0;
2308        priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2309        priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2310        priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI);
2311        priv->ieee80211->qos_support = 1;
2312        priv->ieee80211->dot11PowerSaveMode = 0;
2313        //added by WB
2314//      priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2315        priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2316        priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2317        priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2318
2319        priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup;
2320//      priv->ieee80211->ps_request_tx_ack = rtl8192_rq_tx_ack;
2321        priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep;
2322        priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty;
2323        //added by david
2324        priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci;
2325        priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2326        priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci;
2327
2328        //added by amy
2329        priv->ieee80211->InitialGainHandler = InitialGain819xPci;
2330
2331        priv->card_type = USB;
2332        {
2333                priv->ShortRetryLimit = 0x30;
2334                priv->LongRetryLimit = 0x30;
2335        }
2336        priv->EarlyRxThreshold = 7;
2337        priv->enable_gpio0 = 0;
2338
2339        priv->TransmitConfig = 0;
2340
2341        priv->ReceiveConfig = RCR_ADD3  |
2342                RCR_AMF | RCR_ADF |             //accept management/data
2343                RCR_AICV |                      //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2344                RCR_AB | RCR_AM | RCR_APM |     //accept BC/MC/UC
2345                RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) |
2346                ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT;
2347
2348        priv->irq_mask =        (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK |\
2349                                IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK |\
2350                                IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW    |\
2351                                IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER);
2352
2353        priv->AcmControl = 0;
2354        priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware));
2355        if (priv->pFirmware)
2356        memset(priv->pFirmware, 0, sizeof(rt_firmware));
2357
2358        /* rx related queue */
2359        skb_queue_head_init(&priv->rx_queue);
2360        skb_queue_head_init(&priv->skb_queue);
2361
2362        /* Tx related queue */
2363        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2364                skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2365        }
2366        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2367                skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2368        }
2369        priv->rf_set_chan = rtl8192_phy_SwChnl;
2370}
2371
2372//init lock here
2373static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2374{
2375        spin_lock_init(&priv->tx_lock);
2376        spin_lock_init(&priv->irq_lock);//added by thomas
2377        spin_lock_init(&priv->irq_th_lock);
2378        spin_lock_init(&priv->rf_ps_lock);
2379        spin_lock_init(&priv->ps_lock);
2380        //spin_lock_init(&priv->rf_lock);
2381        sema_init(&priv->wx_sem,1);
2382        sema_init(&priv->rf_sem,1);
2383        mutex_init(&priv->mutex);
2384}
2385
2386extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
2387
2388void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2389void rtl8192_irq_tx_tasklet(struct r8192_priv *priv);
2390void rtl8192_prepare_beacon(struct r8192_priv *priv);
2391//init tasklet and wait_queue here. only 2.6 above kernel is considered
2392#define DRV_NAME "wlan0"
2393static void rtl8192_init_priv_task(struct net_device* dev)
2394{
2395        struct r8192_priv *priv = ieee80211_priv(dev);
2396
2397#ifdef PF_SYNCTHREAD
2398        priv->priv_wq = create_workqueue(DRV_NAME,0);
2399#else
2400        priv->priv_wq = create_workqueue(DRV_NAME);
2401#endif
2402
2403//      INIT_WORK(&priv->reset_wq, (void(*)(void*)) rtl8192_restart);
2404        INIT_WORK(&priv->reset_wq,  rtl8192_restart);
2405//      INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2406        INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2407        INIT_DELAYED_WORK(&priv->txpower_tracking_wq,  dm_txpower_trackingcallback);
2408        INIT_DELAYED_WORK(&priv->rfpath_check_wq,  dm_rf_pathcheck_workitemcallback);
2409        INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2410        //INIT_WORK(&priv->SwChnlWorkItem,  rtl8192_SwChnl_WorkItem);
2411        //INIT_WORK(&priv->SetBWModeWorkItem,  rtl8192_SetBWModeWorkItem);
2412        INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2413        INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8192_hw_wakeup_wq);
2414        INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8192_hw_sleep_wq);
2415
2416        tasklet_init(&priv->irq_rx_tasklet,
2417             (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2418             (unsigned long)priv);
2419        tasklet_init(&priv->irq_tx_tasklet,
2420             (void(*)(unsigned long))rtl8192_irq_tx_tasklet,
2421             (unsigned long)priv);
2422        tasklet_init(&priv->irq_prepare_beacon_tasklet,
2423                (void(*)(unsigned long))rtl8192_prepare_beacon,
2424                (unsigned long)priv);
2425}
2426
2427static void rtl8192_get_eeprom_size(struct net_device* dev)
2428{
2429        u16 curCR = 0;
2430        struct r8192_priv *priv = ieee80211_priv(dev);
2431        RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__);
2432        curCR = read_nic_dword(dev, EPROM_CMD);
2433        RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR);
2434        //whether need I consider BIT5?
2435        priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2436        RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2437}
2438
2439//used to swap endian. as ntohl & htonl are not neccessary to swap endian, so use this instead.
2440static inline u16 endian_swap(u16* data)
2441{
2442        u16 tmp = *data;
2443        *data = (tmp >> 8) | (tmp << 8);
2444        return *data;
2445}
2446
2447/*
2448 *      Note:   Adapter->EEPROMAddressSize should be set before this function call.
2449 *                      EEPROM address size can be got through GetEEPROMSize8185()
2450*/
2451static void rtl8192_read_eeprom_info(struct net_device* dev)
2452{
2453        struct r8192_priv *priv = ieee80211_priv(dev);
2454
2455        u8                      tempval;
2456#ifdef RTL8192E
2457        u8                      ICVer8192, ICVer8256;
2458#endif
2459        u16                     i,usValue, IC_Version;
2460        u16                     EEPROMId;
2461#ifdef RTL8190P
2462        u8                      offset;//, tmpAFR;
2463        u8                      EepromTxPower[100];
2464#endif
2465        u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01};
2466        RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n");
2467
2468
2469        // TODO: I don't know if we need to apply EF function to EEPROM read function
2470
2471        //2 Read EEPROM ID to make sure autoload is success
2472        EEPROMId = eprom_read(dev, 0);
2473        if( EEPROMId != RTL8190_EEPROM_ID )
2474        {
2475                RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID);
2476                priv->AutoloadFailFlag=true;
2477        }
2478        else
2479        {
2480                priv->AutoloadFailFlag=false;
2481        }
2482
2483        //
2484        // Assign Chip Version ID
2485        //
2486        // Read IC Version && Channel Plan
2487        if(!priv->AutoloadFailFlag)
2488        {
2489                // VID, PID
2490                priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1));
2491                priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1));
2492
2493                usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8 ;
2494                priv->eeprom_CustomerID = (u8)( usValue & 0xff);
2495                usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1));
2496                priv->eeprom_ChannelPlan = usValue&0xff;
2497                IC_Version = ((usValue&0xff00)>>8);
2498
2499#ifdef RTL8190P
2500                priv->card_8192_version = (VERSION_8190)(IC_Version);
2501#else
2502        #ifdef RTL8192E
2503                ICVer8192 = (IC_Version&0xf);           //bit0~3; 1:A cut, 2:B cut, 3:C cut...
2504                ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut...
2505                RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192);
2506                RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256);
2507                if(ICVer8192 == 0x2)    //B-cut
2508                {
2509                        if(ICVer8256 == 0x5) //E-cut
2510                                priv->card_8192_version= VERSION_8190_BE;
2511                }
2512        #endif
2513#endif
2514                switch(priv->card_8192_version)
2515                {
2516                        case VERSION_8190_BD:
2517                        case VERSION_8190_BE:
2518                                break;
2519                        default:
2520                                priv->card_8192_version = VERSION_8190_BD;
2521                                break;
2522                }
2523                RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version);
2524        }
2525        else
2526        {
2527                priv->card_8192_version = VERSION_8190_BD;
2528                priv->eeprom_vid = 0;
2529                priv->eeprom_did = 0;
2530                priv->eeprom_CustomerID = 0;
2531                priv->eeprom_ChannelPlan = 0;
2532                RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff);
2533        }
2534
2535        RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid);
2536        RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did);
2537        RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID);
2538
2539        //2 Read Permanent MAC address
2540        if(!priv->AutoloadFailFlag)
2541        {
2542                for(i = 0; i < 6; i += 2)
2543                {
2544                        usValue = eprom_read(dev, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1));
2545                        *(u16*)(&dev->dev_addr[i]) = usValue;
2546                }
2547        } else {
2548                // when auto load failed,  the last address byte set to be a random one.
2549                // added by david woo.2007/11/7
2550                memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2551        }
2552
2553        RT_TRACE(COMP_INIT, "Permanent Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
2554                        dev->dev_addr[0], dev->dev_addr[1],
2555                        dev->dev_addr[2], dev->dev_addr[3],
2556                        dev->dev_addr[4], dev->dev_addr[5]);
2557
2558                //2 TX Power Check EEPROM Fail or not
2559        if(priv->card_8192_version > VERSION_8190_BD) {
2560                priv->bTXPowerDataReadFromEEPORM = true;
2561        } else {
2562                priv->bTXPowerDataReadFromEEPORM = false;
2563        }
2564
2565        // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE dafault=1T2R
2566        priv->rf_type = RTL819X_DEFAULT_RF_TYPE;
2567
2568        if(priv->card_8192_version > VERSION_8190_BD)
2569        {
2570                // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate.
2571                if(!priv->AutoloadFailFlag)
2572                {
2573                        tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff>>1))) & 0xff;
2574                        priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf;        // bit[3:0]
2575
2576                        if (tempval&0x80)       //RF-indication, bit[7]
2577                                priv->rf_type = RF_1T2R;
2578                        else
2579                                priv->rf_type = RF_2T4R;
2580                }
2581                else
2582                {
2583                        priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff;
2584                }
2585                RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n",
2586                        priv->EEPROMLegacyHTTxPowerDiff);
2587
2588                // Read ThermalMeter from EEPROM
2589                if(!priv->AutoloadFailFlag)
2590                {
2591                        priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8);
2592                }
2593                else
2594                {
2595                        priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2596                }
2597                RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter);
2598                //vivi, for tx power track
2599                priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2600
2601                if(priv->epromtype == EPROM_93c46)
2602                {
2603                // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM
2604                if(!priv->AutoloadFailFlag)
2605                {
2606                                usValue = eprom_read(dev, (EEPROM_TxPwDiff_CrystalCap>>1));
2607                                priv->EEPROMAntPwDiff = (usValue&0x0fff);
2608                                priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12);
2609                }
2610                else
2611                {
2612                                priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2613                                priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2614                }
2615                        RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2616                        RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2617
2618                //
2619                // Get per-channel Tx Power Level
2620                //
2621                for(i=0; i<14; i+=2)
2622                {
2623                        if(!priv->AutoloadFailFlag)
2624                        {
2625                                usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) );
2626                        }
2627                        else
2628                        {
2629                                usValue = EEPROM_Default_TxPower;
2630                        }
2631                        *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue;
2632                        RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]);
2633                        RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]);
2634                }
2635                for(i=0; i<14; i+=2)
2636                {
2637                        if(!priv->AutoloadFailFlag)
2638                        {
2639                                usValue = eprom_read(dev, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) );
2640                        }
2641                        else
2642                        {
2643                                usValue = EEPROM_Default_TxPower;
2644                        }
2645                        *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue;
2646                        RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]);
2647                        RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]);
2648                }
2649                }
2650                else if(priv->epromtype== EPROM_93c56)
2651                {
2652                #ifdef RTL8190P
2653                        // Read CrystalCap from EEPROM
2654                        if(!priv->AutoloadFailFlag)
2655                        {
2656                                priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2657                                priv->EEPROMCrystalCap = (u8)(((eprom_read(dev, (EEPROM_C56_CrystalCap>>1))) & 0xf000)>>12);
2658                        }
2659                        else
2660                        {
2661                                priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff;
2662                                priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap;
2663                        }
2664                        RT_TRACE(COMP_INIT,"EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff);
2665                        RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap);
2666
2667                        // Get Tx Power Level by Channel
2668                        if(!priv->AutoloadFailFlag)
2669                        {
2670                                    // Read Tx power of Channel 1 ~ 14 from EEPROM.
2671                               for(i = 0; i < 12; i+=2)
2672                                {
2673                                        if (i <6)
2674                                                offset = EEPROM_C56_RfA_CCK_Chnl1_TxPwIndex + i;
2675                                        else
2676                                                offset = EEPROM_C56_RfC_CCK_Chnl1_TxPwIndex + i - 6;
2677                                        usValue = eprom_read(dev, (offset>>1));
2678                                       *((u16*)(&EepromTxPower[i])) = usValue;
2679                                }
2680
2681                               for(i = 0; i < 12; i++)
2682                                {
2683                                        if (i <= 2)
2684                                                priv->EEPROMRfACCKChnl1TxPwLevel[i] = EepromTxPower[i];
2685                                        else if ((i >=3 )&&(i <= 5))
2686                                                priv->EEPROMRfAOfdmChnlTxPwLevel[i-3] = EepromTxPower[i];
2687                                        else if ((i >=6 )&&(i <= 8))
2688                                                priv->EEPROMRfCCCKChnl1TxPwLevel[i-6] = EepromTxPower[i];
2689                                        else
2690                                                priv->EEPROMRfCOfdmChnlTxPwLevel[i-9] = EepromTxPower[i];
2691                                }
2692                        }
2693                        else
2694                        {
2695                                priv->EEPROMRfACCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2696                                priv->EEPROMRfACCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2697                                priv->EEPROMRfACCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2698
2699                                priv->EEPROMRfAOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2700                                priv->EEPROMRfAOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2701                                priv->EEPROMRfAOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2702
2703                                priv->EEPROMRfCCCKChnl1TxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2704                                priv->EEPROMRfCCCKChnl1TxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2705                                priv->EEPROMRfCCCKChnl1TxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2706
2707                                priv->EEPROMRfCOfdmChnlTxPwLevel[0] = EEPROM_Default_TxPowerLevel;
2708                                priv->EEPROMRfCOfdmChnlTxPwLevel[1] = EEPROM_Default_TxPowerLevel;
2709                                priv->EEPROMRfCOfdmChnlTxPwLevel[2] = EEPROM_Default_TxPowerLevel;
2710                        }
2711                        RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[0]);
2712                        RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[1]);
2713                        RT_TRACE(COMP_INIT, "priv->EEPROMRfACCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfACCKChnl1TxPwLevel[2]);
2714                        RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[0]);
2715                        RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[1]);
2716                        RT_TRACE(COMP_INIT, "priv->EEPROMRfAOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfAOfdmChnlTxPwLevel[2]);
2717                        RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[0] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[0]);
2718                        RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[1] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[1]);
2719                        RT_TRACE(COMP_INIT, "priv->EEPROMRfCCCKChnl1TxPwLevel[2] = 0x%x\n", priv->EEPROMRfCCCKChnl1TxPwLevel[2]);
2720                        RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[0] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[0]);
2721                        RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[1] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[1]);
2722                        RT_TRACE(COMP_INIT, "priv->EEPROMRfCOfdmChnlTxPwLevel[2] = 0x%x\n", priv->EEPROMRfCOfdmChnlTxPwLevel[2]);
2723#endif
2724
2725                }
2726                //
2727                // Update HAL variables.
2728                //
2729                if(priv->epromtype == EPROM_93c46)
2730                {
2731                        for(i=0; i<14; i++)
2732                        {
2733                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i];
2734                                priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i];
2735                        }
2736                        priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2737                // Antenna B gain offset to antenna A, bit0~3
2738                        priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf);
2739                // Antenna C gain offset to antenna A, bit4~7
2740                        priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4);
2741                // Antenna D gain offset to antenna A, bit8~11
2742                        priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8);
2743                // CrystalCap, bit12~15
2744                        priv->CrystalCap = priv->EEPROMCrystalCap;
2745                // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2746                        priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2747                        priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2748                }
2749                else if(priv->epromtype == EPROM_93c56)
2750                {
2751                        //char  cck_pwr_diff_a=0, cck_pwr_diff_c=0;
2752
2753                        //cck_pwr_diff_a = pHalData->EEPROMRfACCKChnl7TxPwLevel - pHalData->EEPROMRfAOfdmChnlTxPwLevel[1];
2754                        //cck_pwr_diff_c = pHalData->EEPROMRfCCCKChnl7TxPwLevel - pHalData->EEPROMRfCOfdmChnlTxPwLevel[1];
2755                        for(i=0; i<3; i++)      // channel 1~3 use the same Tx Power Level.
2756                        {
2757                                priv->TxPowerLevelCCK_A[i]  = priv->EEPROMRfACCKChnl1TxPwLevel[0];
2758                                priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0];
2759                                priv->TxPowerLevelCCK_C[i] =  priv->EEPROMRfCCCKChnl1TxPwLevel[0];
2760                                priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0];
2761                        }
2762                        for(i=3; i<9; i++)      // channel 4~9 use the same Tx Power Level
2763                        {
2764                                priv->TxPowerLevelCCK_A[i]  = priv->EEPROMRfACCKChnl1TxPwLevel[1];
2765                                priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1];
2766                                priv->TxPowerLevelCCK_C[i] =  priv->EEPROMRfCCCKChnl1TxPwLevel[1];
2767                                priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1];
2768                        }
2769                        for(i=9; i<14; i++)     // channel 10~14 use the same Tx Power Level
2770                        {
2771                                priv->TxPowerLevelCCK_A[i]  = priv->EEPROMRfACCKChnl1TxPwLevel[2];
2772                                priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2];
2773                                priv->TxPowerLevelCCK_C[i] =  priv->EEPROMRfCCCKChnl1TxPwLevel[2];
2774                                priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2];
2775                        }
2776                        for(i=0; i<14; i++)
2777                                RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]);
2778                        for(i=0; i<14; i++)
2779                                RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]);
2780                        for(i=0; i<14; i++)
2781                                RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]);
2782                        for(i=0; i<14; i++)
2783                                RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]);
2784                        priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff;
2785                        priv->AntennaTxPwDiff[0] = 0;
2786                        priv->AntennaTxPwDiff[1] = 0;
2787                        priv->AntennaTxPwDiff[2] = 0;
2788                        priv->CrystalCap = priv->EEPROMCrystalCap;
2789                        // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
2790                        priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf);
2791                        priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4);
2792                }
2793        }
2794
2795        if(priv->rf_type == RF_1T2R)
2796        {
2797                RT_TRACE(COMP_INIT, "\n1T2R config\n");
2798        }
2799        else if (priv->rf_type == RF_2T4R)
2800        {
2801                RT_TRACE(COMP_INIT, "\n2T4R config\n");
2802        }
2803
2804        // 2008/01/16 MH We can only know RF type in the function. So we have to init
2805        // DIG RATR table again.
2806        init_rate_adaptive(dev);
2807
2808        //1 Make a copy for following variables and we can change them if we want
2809
2810        priv->rf_chip= RF_8256;
2811
2812        if(priv->RegChannelPlan == 0xf)
2813        {
2814                priv->ChannelPlan = priv->eeprom_ChannelPlan;
2815        }
2816        else
2817        {
2818                priv->ChannelPlan = priv->RegChannelPlan;
2819        }
2820
2821        //
2822        //  Used PID and DID to Set CustomerID
2823        //
2824        if( priv->eeprom_vid == 0x1186 &&  priv->eeprom_did == 0x3304 )
2825        {
2826                priv->CustomerID =  RT_CID_DLINK;
2827        }
2828
2829        switch(priv->eeprom_CustomerID)
2830        {
2831                case EEPROM_CID_DEFAULT:
2832                        priv->CustomerID = RT_CID_DEFAULT;
2833                        break;
2834                case EEPROM_CID_CAMEO:
2835                        priv->CustomerID = RT_CID_819x_CAMEO;
2836                        break;
2837                case  EEPROM_CID_RUNTOP:
2838                        priv->CustomerID = RT_CID_819x_RUNTOP;
2839                        break;
2840                case EEPROM_CID_NetCore:
2841                        priv->CustomerID = RT_CID_819x_Netcore;
2842                        break;
2843                case EEPROM_CID_TOSHIBA:        // Merge by Jacken, 2008/01/31
2844                        priv->CustomerID = RT_CID_TOSHIBA;
2845                        if(priv->eeprom_ChannelPlan&0x80)
2846                                priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f;
2847                        else
2848                                priv->ChannelPlan = 0x0;
2849                        RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n",
2850                                priv->ChannelPlan);
2851                        break;
2852                case EEPROM_CID_Nettronix:
2853                        priv->ScanDelay = 100;  //cosa add for scan
2854                        priv->CustomerID = RT_CID_Nettronix;
2855                        break;
2856                case EEPROM_CID_Pronet:
2857                        priv->CustomerID = RT_CID_PRONET;
2858                        break;
2859                case EEPROM_CID_DLINK:
2860                        priv->CustomerID = RT_CID_DLINK;
2861                        break;
2862
2863                case EEPROM_CID_WHQL:
2864                        //Adapter->bInHctTest = TRUE;//do not supported
2865
2866                        //priv->bSupportTurboMode = FALSE;
2867                        //priv->bAutoTurboBy8186 = FALSE;
2868
2869                        //pMgntInfo->PowerSaveControl.bInactivePs = FALSE;
2870                        //pMgntInfo->PowerSaveControl.bIPSModeBackup = FALSE;
2871                        //pMgntInfo->PowerSaveControl.bLeisurePs = FALSE;
2872
2873                        break;
2874                default:
2875                        // value from RegCustomerID
2876                        break;
2877        }
2878
2879        //Avoid the channel plan array overflow, by Bruce, 2007-08-27.
2880        if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1)
2881                priv->ChannelPlan = 0; //FCC
2882
2883        switch(priv->CustomerID)
2884        {
2885                case RT_CID_DEFAULT:
2886                #ifdef RTL8190P
2887                        priv->LedStrategy = HW_LED;
2888                #else
2889                        #ifdef RTL8192E
2890                        priv->LedStrategy = SW_LED_MODE1;
2891                        #endif
2892                #endif
2893                        break;
2894
2895                case RT_CID_819x_CAMEO:
2896                        priv->LedStrategy = SW_LED_MODE2;
2897                        break;
2898
2899                case RT_CID_819x_RUNTOP:
2900                        priv->LedStrategy = SW_LED_MODE3;
2901                        break;
2902
2903                case RT_CID_819x_Netcore:
2904                        priv->LedStrategy = SW_LED_MODE4;
2905                        break;
2906
2907                case RT_CID_Nettronix:
2908                        priv->LedStrategy = SW_LED_MODE5;
2909                        break;
2910
2911                case RT_CID_PRONET:
2912                        priv->LedStrategy = SW_LED_MODE6;
2913                        break;
2914
2915                case RT_CID_TOSHIBA:   //Modify by Jacken 2008/01/31
2916                        // Do nothing.
2917                        //break;
2918
2919                default:
2920                #ifdef RTL8190P
2921                        priv->LedStrategy = HW_LED;
2922                #else
2923                        #ifdef RTL8192E
2924                        priv->LedStrategy = SW_LED_MODE1;
2925                        #endif
2926                #endif
2927                        break;
2928        }
2929/*
2930        //2008.06.03, for WOL
2931        if( priv->eeprom_vid == 0x1186 &&  priv->eeprom_did == 0x3304)
2932                priv->ieee80211->bSupportRemoteWakeUp = TRUE;
2933        else
2934                priv->ieee80211->bSupportRemoteWakeUp = FALSE;
2935*/
2936        RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan);
2937        RT_TRACE(COMP_INIT, "ChannelPlan = %d \n", priv->ChannelPlan);
2938        RT_TRACE(COMP_INIT, "LedStrategy = %d \n", priv->LedStrategy);
2939        RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n");
2940
2941        return ;
2942}
2943
2944
2945static short rtl8192_get_channel_map(struct net_device * dev)
2946{
2947        struct r8192_priv *priv = ieee80211_priv(dev);
2948#ifdef ENABLE_DOT11D
2949        if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){
2950                printk("rtl8180_init:Error channel plan! Set to default.\n");
2951                priv->ChannelPlan= 0;
2952        }
2953        RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
2954
2955        rtl819x_set_channel_map(priv->ChannelPlan, priv);
2956#else
2957        int ch,i;
2958        //Set Default Channel Plan
2959        if(!channels){
2960                DMESG("No channels, aborting");
2961                return -1;
2962        }
2963        ch=channels;
2964        priv->ChannelPlan= 0;//hikaru
2965         // set channels 1..14 allowed in given locale
2966        for (i=1; i<=14; i++) {
2967                (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
2968                ch >>= 1;
2969        }
2970#endif
2971        return 0;
2972}
2973
2974static short rtl8192_init(struct net_device *dev)
2975{
2976        struct r8192_priv *priv = ieee80211_priv(dev);
2977        memset(&(priv->stats),0,sizeof(struct Stats));
2978        rtl8192_init_priv_variable(dev);
2979        rtl8192_init_priv_lock(priv);
2980        rtl8192_init_priv_task(dev);
2981        rtl8192_get_eeprom_size(dev);
2982        rtl8192_read_eeprom_info(dev);
2983        rtl8192_get_channel_map(dev);
2984        init_hal_dm(dev);
2985        init_timer(&priv->watch_dog_timer);
2986        priv->watch_dog_timer.data = (unsigned long)dev;
2987        priv->watch_dog_timer.function = watch_dog_timer_callback;
2988#if defined(IRQF_SHARED)
2989        if(request_irq(dev->irq, (void*)rtl8192_interrupt, IRQF_SHARED, dev->name, dev)){
2990#else
2991        if(request_irq(dev->irq, (void *)rtl8192_interrupt, SA_SHIRQ, dev->name, dev)){
2992#endif
2993                printk("Error allocating IRQ %d",dev->irq);
2994                return -1;
2995        }else{
2996                priv->irq=dev->irq;
2997                printk("IRQ %d",dev->irq);
2998        }
2999        if(rtl8192_pci_initdescring(dev)!=0){
3000                printk("Endopoints initialization failed");
3001                return -1;
3002        }
3003
3004        //rtl8192_rx_enable(dev);
3005        //rtl8192_adapter_start(dev);
3006        return 0;
3007}
3008
3009/******************************************************************************
3010 *function:  This function actually only set RRSR, RATR and BW_OPMODE registers
3011 *           not to do all the hw config as its name says
3012 *   input:  net_device dev
3013 *  output:  none
3014 *  return:  none
3015 *  notice:  This part need to modified according to the rate set we filtered
3016 * ****************************************************************************/
3017static void rtl8192_hwconfig(struct net_device* dev)
3018{
3019        u32 regRATR = 0, regRRSR = 0;
3020        u8 regBwOpMode = 0, regTmp = 0;
3021        struct r8192_priv *priv = ieee80211_priv(dev);
3022
3023// Set RRSR, RATR, and BW_OPMODE registers
3024        //
3025        switch(priv->ieee80211->mode)
3026        {
3027        case WIRELESS_MODE_B:
3028                regBwOpMode = BW_OPMODE_20MHZ;
3029                regRATR = RATE_ALL_CCK;
3030                regRRSR = RATE_ALL_CCK;
3031                break;
3032        case WIRELESS_MODE_A:
3033                regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3034                regRATR = RATE_ALL_OFDM_AG;
3035                regRRSR = RATE_ALL_OFDM_AG;
3036                break;
3037        case WIRELESS_MODE_G:
3038                regBwOpMode = BW_OPMODE_20MHZ;
3039                regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3040                regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3041                break;
3042        case WIRELESS_MODE_AUTO:
3043        case WIRELESS_MODE_N_24G:
3044                // It support CCK rate by default.
3045                // CCK rate will be filtered out only when associated AP does not support it.
3046                regBwOpMode = BW_OPMODE_20MHZ;
3047                        regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3048                        regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3049                break;
3050        case WIRELESS_MODE_N_5G:
3051                regBwOpMode = BW_OPMODE_5G;
3052                regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3053                regRRSR = RATE_ALL_OFDM_AG;
3054                break;
3055        }
3056
3057        write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3058        {
3059                u32 ratr_value = 0;
3060                ratr_value = regRATR;
3061                if (priv->rf_type == RF_1T2R)
3062                {
3063                        ratr_value &= ~(RATE_ALL_OFDM_2SS);
3064                }
3065                write_nic_dword(dev, RATR0, ratr_value);
3066                write_nic_byte(dev, UFWP, 1);
3067        }
3068        regTmp = read_nic_byte(dev, 0x313);
3069        regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3070        write_nic_dword(dev, RRSR, regRRSR);
3071
3072        //
3073        // Set Retry Limit here
3074        //
3075        write_nic_word(dev, RETRY_LIMIT,
3076                        priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3077                        priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3078        // Set Contention Window here
3079
3080        // Set Tx AGC
3081
3082        // Set Tx Antenna including Feedback control
3083
3084        // Set Auto Rate fallback control
3085
3086
3087}
3088
3089
3090static RT_STATUS rtl8192_adapter_start(struct net_device *dev)
3091{
3092        struct r8192_priv *priv = ieee80211_priv(dev);
3093//      struct ieee80211_device *ieee = priv->ieee80211;
3094        u32 ulRegRead;
3095        RT_STATUS rtStatus = RT_STATUS_SUCCESS;
3096//      static char szMACPHYRegFile[] = RTL819X_PHY_MACPHY_REG;
3097//      static char szMACPHYRegPGFile[] = RTL819X_PHY_MACPHY_REG_PG;
3098        //u8 eRFPath;
3099        u8 tmpvalue;
3100#ifdef RTL8192E
3101        u8 ICVersion,SwitchingRegulatorOutput;
3102#endif
3103        bool bfirmwareok = true;
3104#ifdef RTL8190P
3105        u8 ucRegRead;
3106#endif
3107        u32     tmpRegA, tmpRegC, TempCCk;
3108        int     i =0;
3109//      u32 dwRegRead = 0;
3110
3111        RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3112        priv->being_init_adapter = true;
3113        rtl8192_pci_resetdescring(dev);
3114        // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W.
3115        priv->Rf_Mode = RF_OP_By_SW_3wire;
3116#ifdef RTL8192E
3117        //dPLL on
3118        if(priv->ResetProgress == RESET_TYPE_NORESET)
3119        {
3120            write_nic_byte(dev, ANAPAR, 0x37);
3121            // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms
3122            // Joseph increae the time to prevent firmware download fail
3123            mdelay(500);
3124        }
3125#endif
3126        //PlatformSleepUs(10000);
3127        // For any kind of InitializeAdapter process, we shall use system now!!
3128        priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3129
3130        // Set to eRfoff in order not to count receive count.
3131        if(priv->RegRfOff == TRUE)
3132                priv->ieee80211->eRFPowerState = eRfOff;
3133
3134        //
3135        //3 //Config CPUReset Register
3136        //3//
3137        //3 Firmware Reset Or Not
3138        ulRegRead = read_nic_dword(dev, CPU_GEN);
3139        if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3140        {       //called from MPInitialized. do nothing
3141                ulRegRead |= CPU_GEN_SYSTEM_RESET;
3142        }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3143                ulRegRead |= CPU_GEN_FIRMWARE_RESET;    // Called from MPReset
3144        else
3145                RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
3146
3147#ifdef RTL8190P
3148        //2008.06.03, for WOL 90 hw bug
3149        ulRegRead &= (~(CPU_GEN_GPIO_UART));
3150#endif
3151
3152        write_nic_dword(dev, CPU_GEN, ulRegRead);
3153        //mdelay(100);
3154
3155#ifdef RTL8192E
3156
3157        //3//
3158        //3 //Fix the issue of E-cut high temperature issue
3159        //3//
3160        // TODO: E cut only
3161        ICVersion = read_nic_byte(dev, IC_VERRSION);
3162        if(ICVersion >= 0x4) //E-cut only
3163        {
3164                // HW SD suggest that we should not wirte this register too often, so driver
3165                // should readback this register. This register will be modified only when
3166                // power on reset
3167                SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR);
3168                if(SwitchingRegulatorOutput  != 0xb8)
3169                {
3170                        write_nic_byte(dev, SWREGULATOR, 0xa8);
3171                        mdelay(1);
3172                        write_nic_byte(dev, SWREGULATOR, 0xb8);
3173                }
3174        }
3175#endif
3176
3177
3178        //3//
3179        //3// Initialize BB before MAC
3180        //3//
3181        RT_TRACE(COMP_INIT, "BB Config Start!\n");
3182        rtStatus = rtl8192_BBConfig(dev);
3183        if(rtStatus != RT_STATUS_SUCCESS)
3184        {
3185                RT_TRACE(COMP_ERR, "BB Config failed\n");
3186                return rtStatus;
3187        }
3188        RT_TRACE(COMP_INIT,"BB Config Finished!\n");
3189
3190        //3//Set Loopback mode or Normal mode
3191        //3//
3192        //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings
3193        //      because setting of System_Reset bit reset MAC to default transmission mode.
3194                //Loopback mode or not
3195        priv->LoopbackMode = RTL819X_NO_LOOPBACK;
3196        //priv->LoopbackMode = RTL819X_MAC_LOOPBACK;
3197        if(priv->ResetProgress == RESET_TYPE_NORESET)
3198        {
3199        ulRegRead = read_nic_dword(dev, CPU_GEN);
3200        if(priv->LoopbackMode == RTL819X_NO_LOOPBACK)
3201        {
3202                ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3203        }
3204        else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK )
3205        {
3206                ulRegRead |= CPU_CCK_LOOPBACK;
3207        }
3208        else
3209        {
3210                RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n");
3211        }
3212
3213        //2008.06.03, for WOL
3214        //ulRegRead &= (~(CPU_GEN_GPIO_UART));
3215        write_nic_dword(dev, CPU_GEN, ulRegRead);
3216
3217        // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily
3218        udelay(500);
3219        }
3220        //3Set Hardware(Do nothing now)
3221        rtl8192_hwconfig(dev);
3222        //2=======================================================
3223        // Common Setting for all of the FPGA platform. (part 1)
3224        //2=======================================================
3225        // If there is changes, please make sure it applies to all of the FPGA version
3226        //3 Turn on Tx/Rx
3227        write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3228
3229        //2Set Tx dma burst
3230#ifdef RTL8190P
3231        write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | \
3232                                                                                        (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) | \
3233                                                                                        (1<<MULRW_SHIFT)));
3234#else
3235        #ifdef RTL8192E
3236        write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) |\
3237                                   (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) ));
3238        #endif
3239#endif
3240        //set IDR0 here
3241        write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3242        write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3243        //set RCR
3244        write_nic_dword(dev, RCR, priv->ReceiveConfig);
3245
3246        //3 Initialize Number of Reserved Pages in Firmware Queue
3247        #ifdef TO_DO_LIST
3248        if(priv->bInHctTest)
3249        {
3250                PlatformEFIOWrite4Byte(Adapter, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3251                                        NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3252                                        NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3253                                        NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3254                PlatformEFIOWrite4Byte(Adapter, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3255                PlatformEFIOWrite4Byte(Adapter, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3256                                        NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3257                                        NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3258        }
3259        else
3260        #endif
3261        {
3262                write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3263                                        NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3264                                        NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3265                                        NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3266                write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT);
3267                write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3268                                        NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT|\
3269                                        NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT);
3270        }
3271
3272        rtl8192_tx_enable(dev);
3273        rtl8192_rx_enable(dev);
3274        //3Set Response Rate Setting Register
3275        // CCK rate is supported by default.
3276        // CCK rate will be filtered out only when associated AP does not support it.
3277        ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR))  | RATE_ALL_OFDM_AG | RATE_ALL_CCK;
3278        write_nic_dword(dev, RRSR, ulRegRead);
3279        write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3280
3281        //2Set AckTimeout
3282        // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3283        write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3284
3285        //rtl8192_actset_wirelessmode(dev,priv->RegWirelessMode);
3286        if(priv->ResetProgress == RESET_TYPE_NORESET)
3287        rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3288        //-----------------------------------------------------------------------------
3289        // Set up security related. 070106, by rcnjko:
3290        // 1. Clear all H/W keys.
3291        // 2. Enable H/W encryption/decryption.
3292        //-----------------------------------------------------------------------------
3293        CamResetAllEntry(dev);
3294        {
3295                u8 SECR_value = 0x0;
3296                SECR_value |= SCR_TxEncEnable;
3297                SECR_value |= SCR_RxDecEnable;
3298                SECR_value |= SCR_NoSKMC;
3299                write_nic_byte(dev, SECR, SECR_value);
3300        }
3301        //3Beacon related
3302        write_nic_word(dev, ATIMWND, 2);
3303        write_nic_word(dev, BCN_INTERVAL, 100);
3304        for (i=0; i<QOS_QUEUE_NUM; i++)
3305                write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
3306        //
3307        // Switching regulator controller: This is set temporarily.
3308        // It's not sure if this can be removed in the future.
3309        // PJ advised to leave it by default.
3310        //
3311        write_nic_byte(dev, 0xbe, 0xc0);
3312
3313        //2=======================================================
3314        // Set PHY related configuration defined in MAC register bank
3315        //2=======================================================
3316        rtl8192_phy_configmac(dev);
3317
3318        if (priv->card_8192_version > (u8) VERSION_8190_BD) {
3319                rtl8192_phy_getTxPower(dev);
3320                rtl8192_phy_setTxPower(dev, priv->chan);
3321        }
3322
3323        //if D or C cut
3324                tmpvalue = read_nic_byte(dev, IC_VERRSION);
3325                priv->IC_Cut = tmpvalue;
3326                RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut);
3327                if(priv->IC_Cut >= IC_VersionCut_D)
3328                {
3329                        //pHalData->bDcut = TRUE;
3330                        if(priv->IC_Cut == IC_VersionCut_D)
3331                                RT_TRACE(COMP_INIT, "D-cut\n");
3332                        if(priv->IC_Cut == IC_VersionCut_E)
3333                        {
3334                                RT_TRACE(COMP_INIT, "E-cut\n");
3335                                // HW SD suggest that we should not wirte this register too often, so driver
3336                                // should readback this register. This register will be modified only when
3337                                // power on reset
3338                        }
3339                }
3340                else
3341                {
3342                        //pHalData->bDcut = FALSE;
3343                        RT_TRACE(COMP_INIT, "Before C-cut\n");
3344                }
3345
3346#if 1
3347        //Firmware download
3348        RT_TRACE(COMP_INIT, "Load Firmware!\n");
3349        bfirmwareok = init_firmware(dev);
3350        if(bfirmwareok != true) {
3351                rtStatus = RT_STATUS_FAILURE;
3352                return rtStatus;
3353        }
3354        RT_TRACE(COMP_INIT, "Load Firmware finished!\n");
3355#endif
3356        //RF config
3357        if(priv->ResetProgress == RESET_TYPE_NORESET)
3358        {
3359        RT_TRACE(COMP_INIT, "RF Config Started!\n");
3360        rtStatus = rtl8192_phy_RFConfig(dev);
3361        if(rtStatus != RT_STATUS_SUCCESS)
3362        {
3363                RT_TRACE(COMP_ERR, "RF Config failed\n");
3364                        return rtStatus;
3365        }
3366        RT_TRACE(COMP_INIT, "RF Config Finished!\n");
3367        }
3368        rtl8192_phy_updateInitGain(dev);
3369
3370        /*---- Set CCK and OFDM Block "ON"----*/
3371        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3372        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3373
3374#ifdef RTL8192E
3375        //Enable Led
3376        write_nic_byte(dev, 0x87, 0x0);
3377#endif
3378#ifdef RTL8190P
3379        //2008.06.03, for WOL
3380        ucRegRead = read_nic_byte(dev, GPE);
3381        ucRegRead |= BIT0;
3382        write_nic_byte(dev, GPE, ucRegRead);
3383
3384        ucRegRead = read_nic_byte(dev, GPO);
3385        ucRegRead &= ~BIT0;
3386        write_nic_byte(dev, GPO, ucRegRead);
3387#endif
3388
3389        //2=======================================================
3390        // RF Power Save
3391        //2=======================================================
3392#ifdef ENABLE_IPS
3393
3394{
3395        if(priv->RegRfOff == TRUE)
3396        { // User disable RF via registry.
3397                RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RegRfOff ----------\n",__FUNCTION__);
3398                MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW);
3399#if 0//cosa, ask SD3 willis and he doesn't know what is this for
3400                // Those action will be discard in MgntActSet_RF_State because off the same state
3401        for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3402                PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3403#endif
3404        }
3405        else if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_PS)
3406        { // H/W or S/W RF OFF before sleep.
3407                RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3408                MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3409        }
3410        else if(priv->ieee80211->RfOffReason >= RF_CHANGE_BY_IPS)
3411        { // H/W or S/W RF OFF before sleep.
3412                RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d) ----------\n", __FUNCTION__,priv->ieee80211->RfOffReason);
3413                MgntActSet_RF_State(dev, eRfOff, priv->ieee80211->RfOffReason);
3414        }
3415        else
3416        {
3417                RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__);
3418                priv->ieee80211->eRFPowerState = eRfOn;
3419                priv->ieee80211->RfOffReason = 0;
3420                //DrvIFIndicateCurrentPhyStatus(Adapter);
3421        // LED control
3422        //Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_ON);
3423
3424        //
3425        // If inactive power mode is enabled, disable rf while in disconnected state.
3426        // But we should still tell upper layer we are in rf on state.
3427        // 2007.07.16, by shien chang.
3428        //
3429                //if(!Adapter->bInHctTest)
3430        //IPSEnter(Adapter);
3431
3432        }
3433}
3434#endif
3435        if(1){
3436#ifdef RTL8192E
3437                        // We can force firmware to do RF-R/W
3438                        if(priv->ieee80211->FwRWRF)
3439                                priv->Rf_Mode = RF_OP_By_FW;
3440                        else
3441                                priv->Rf_Mode = RF_OP_By_SW_3wire;
3442#else
3443                        priv->Rf_Mode = RF_OP_By_SW_3wire;
3444#endif
3445        }
3446#ifdef RTL8190P
3447        if(priv->ResetProgress == RESET_TYPE_NORESET)
3448        {
3449                dm_initialize_txpower_tracking(dev);
3450
3451                tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3452                tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3453
3454                if(priv->rf_type == RF_2T4R){
3455                for(i = 0; i<TxBBGainTableLength; i++)
3456                {
3457                        if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3458                        {
3459                                priv->rfa_txpowertrackingindex= (u8)i;
3460                                priv->rfa_txpowertrackingindex_real= (u8)i;
3461                                priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3462                                break;
3463                        }
3464                }
3465                }
3466                for(i = 0; i<TxBBGainTableLength; i++)
3467                {
3468                        if(tmpRegC == priv->txbbgain_table[i].txbbgain_value)
3469                        {
3470                                priv->rfc_txpowertrackingindex= (u8)i;
3471                                priv->rfc_txpowertrackingindex_real= (u8)i;
3472                                priv->rfc_txpowertracking_default = priv->rfc_txpowertrackingindex;
3473                                break;
3474                        }
3475                }
3476                TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3477
3478                for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3479                {
3480                        if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3481                        {
3482                                priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3483                                break;
3484                        }
3485                }
3486                priv->CCKPresentAttentuation_40Mdefault = 0;
3487                priv->CCKPresentAttentuation_difference = 0;
3488                priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3489                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3490                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3491                RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_initial = %d\n", priv->rfc_txpowertrackingindex);
3492                RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real_initial = %d\n", priv->rfc_txpowertrackingindex_real);
3493                RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3494                RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3495        }
3496#else
3497        #ifdef RTL8192E
3498        if(priv->ResetProgress == RESET_TYPE_NORESET)
3499        {
3500                dm_initialize_txpower_tracking(dev);
3501
3502                if(priv->IC_Cut >= IC_VersionCut_D)
3503                {
3504                        tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3505                        tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3506                        for(i = 0; i<TxBBGainTableLength; i++)
3507                        {
3508                                if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3509                                {
3510                                        priv->rfa_txpowertrackingindex= (u8)i;
3511                                        priv->rfa_txpowertrackingindex_real= (u8)i;
3512                                        priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex;
3513                                        break;
3514                                }
3515                        }
3516
3517                TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3518
3519                for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3520                {
3521                        if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3522                        {
3523                                priv->CCKPresentAttentuation_20Mdefault =(u8) i;
3524                                break;
3525                        }
3526                }
3527                priv->CCKPresentAttentuation_40Mdefault = 0;
3528                priv->CCKPresentAttentuation_difference = 0;
3529                priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault;
3530                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex);
3531                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real);
3532                        RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference);
3533                        RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation);
3534                        priv->btxpower_tracking = FALSE;//TEMPLY DISABLE
3535                }
3536        }
3537        #endif
3538#endif
3539        rtl8192_irq_enable(dev);
3540        priv->being_init_adapter = false;
3541        return rtStatus;
3542
3543}
3544
3545void rtl8192_prepare_beacon(struct r8192_priv *priv)
3546{
3547        struct sk_buff *skb;
3548        //unsigned long flags;
3549        cb_desc *tcb_desc;
3550
3551        skb = ieee80211_get_beacon(priv->ieee80211);
3552        tcb_desc = (cb_desc *)(skb->cb + 8);
3553        //printk("===========> %s\n", __FUNCTION__);
3554        //spin_lock_irqsave(&priv->tx_lock,flags);
3555        /* prepare misc info for the beacon xmit */
3556        tcb_desc->queue_index = BEACON_QUEUE;
3557        /* IBSS does not support HT yet, use 1M defautly */
3558        tcb_desc->data_rate = 2;
3559        tcb_desc->RATRIndex = 7;
3560        tcb_desc->bTxDisableRateFallBack = 1;
3561        tcb_desc->bTxUseDriverAssingedRate = 1;
3562
3563        skb_push(skb, priv->ieee80211->tx_headroom);
3564        if(skb){
3565                rtl8192_tx(priv->ieee80211->dev,skb);
3566        }
3567        //spin_unlock_irqrestore (&priv->tx_lock, flags);
3568}
3569
3570
3571/* this configures registers for beacon tx and enables it via
3572 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3573 * be used to stop beacon transmission
3574 */
3575void rtl8192_start_beacon(struct net_device *dev)
3576{
3577        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
3578        struct ieee80211_network *net = &priv->ieee80211->current_network;
3579        u16 BcnTimeCfg = 0;
3580        u16 BcnCW = 6;
3581        u16 BcnIFS = 0xf;
3582
3583        DMESG("Enabling beacon TX");
3584        //rtl8192_prepare_beacon(dev);
3585        rtl8192_irq_disable(dev);
3586        //rtl8192_beacon_tx_enable(dev);
3587
3588        /* ATIM window */
3589        write_nic_word(dev, ATIMWND, 2);
3590
3591        /* Beacon interval (in unit of TU) */
3592        write_nic_word(dev, BCN_INTERVAL, net->beacon_interval);
3593
3594        /*
3595         * DrvErlyInt (in unit of TU).
3596         * (Time to send interrupt to notify driver to c
3597         * hange beacon content)
3598         * */
3599        write_nic_word(dev, BCN_DRV_EARLY_INT, 10);
3600
3601        /*
3602         * BcnDMATIM(in unit of us).
3603         * Indicates the time before TBTT to perform beacon queue DMA
3604         * */
3605        write_nic_word(dev, BCN_DMATIME, 256);
3606
3607        /*
3608         * Force beacon frame transmission even after receiving
3609         * beacon frame from other ad hoc STA
3610         * */
3611        write_nic_byte(dev, BCN_ERR_THRESH, 100);
3612
3613        /* Set CW and IFS */
3614        BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT;
3615        BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS;
3616        write_nic_word(dev, BCN_TCFG, BcnTimeCfg);
3617
3618
3619        /* enable the interrupt for ad-hoc process */
3620        rtl8192_irq_enable(dev);
3621}
3622/***************************************************************************
3623    -------------------------------NET STUFF---------------------------
3624***************************************************************************/
3625
3626
3627
3628static bool HalTxCheckStuck8190Pci(struct net_device *dev)
3629{
3630        u16                             RegTxCounter = read_nic_word(dev, 0x128);
3631        struct r8192_priv *priv = ieee80211_priv(dev);
3632        bool                            bStuck = FALSE;
3633        RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3634        if(priv->TxCounter==RegTxCounter)
3635                bStuck = TRUE;
3636
3637        priv->TxCounter = RegTxCounter;
3638
3639        return bStuck;
3640}
3641
3642/*
3643*       <Assumption: RT_TX_SPINLOCK is acquired.>
3644*       First added: 2006.11.19 by emily
3645*/
3646static RESET_TYPE
3647TxCheckStuck(struct net_device *dev)
3648{
3649        struct r8192_priv *priv = ieee80211_priv(dev);
3650        u8                      QueueID;
3651        ptx_ring                head=NULL,tail=NULL,txring = NULL;
3652        u8                      ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3653        bool                    bCheckFwTxCnt = false;
3654        //unsigned long flags;
3655
3656        //
3657        // Decide Stuch threshold according to current power save mode
3658        //
3659        //printk("++++++++++++>%s()\n",__FUNCTION__);
3660        switch (priv->ieee80211->dot11PowerSaveMode)
3661        {
3662                // The threshold value  may required to be adjusted .
3663                case eActive:           // Active/Continuous access.
3664                        ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL;
3665                        break;
3666                case eMaxPs:            // Max power save mode.
3667                        ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3668                        break;
3669                case eFastPs:   // Fast power save mode.
3670                        ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE;
3671                        break;
3672        }
3673
3674        //
3675        // Check whether specific tcb has been queued for a specific time
3676        //
3677        for(QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++)
3678        {
3679
3680
3681                if(QueueID == TXCMD_QUEUE)
3682                        continue;
3683
3684                switch(QueueID) {
3685                case MGNT_QUEUE:
3686                        tail=priv->txmapringtail;
3687                        head=priv->txmapringhead;
3688                        break;
3689
3690                case BK_QUEUE:
3691                        tail=priv->txbkpringtail;
3692                        head=priv->txbkpringhead;
3693                        break;
3694
3695                case BE_QUEUE:
3696                        tail=priv->txbepringtail;
3697                        head=priv->txbepringhead;
3698                        break;
3699
3700                case VI_QUEUE:
3701                        tail=priv->txvipringtail;
3702                        head=priv->txvipringhead;
3703                        break;
3704
3705                case VO_QUEUE:
3706                        tail=priv->txvopringtail;
3707                        head=priv->txvopringhead;
3708                        break;
3709
3710                default:
3711                        tail=head=NULL;
3712                        break;
3713                }
3714
3715                if(tail == head)
3716                        continue;
3717                else
3718                {
3719                        txring = head;
3720                        if(txring == NULL)
3721                        {
3722                                RT_TRACE(COMP_ERR,"%s():txring is NULL , BUG!\n",__FUNCTION__);
3723                                continue;
3724                        }
3725                        txring->nStuckCount++;
3726                        bCheckFwTxCnt = TRUE;
3727                }
3728        }
3729#if 1
3730        if(bCheckFwTxCnt)
3731        {
3732                if(HalTxCheckStuck8190Pci(dev))
3733                {
3734                        RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3735                        return RESET_TYPE_SILENT;
3736                }
3737        }
3738#endif
3739        return RESET_TYPE_NORESET;
3740}
3741
3742
3743static bool HalRxCheckStuck8190Pci(struct net_device *dev)
3744{
3745        struct r8192_priv *priv = ieee80211_priv(dev);
3746        u16                             RegRxCounter = read_nic_word(dev, 0x130);
3747        bool                            bStuck = FALSE;
3748        static u8                       rx_chk_cnt = 0;
3749        RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3750        // If rssi is small, we should check rx for long time because of bad rx.
3751        // or maybe it will continuous silent reset every 2 seconds.
3752        rx_chk_cnt++;
3753        if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3754        {
3755                rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3756        }
3757        else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3758                ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3759                (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3760
3761        {
3762                if(rx_chk_cnt < 2)
3763                {
3764                        return bStuck;
3765                }
3766                else
3767                {
3768                        rx_chk_cnt = 0;
3769                }
3770        }
3771        else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3772                (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3773                priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3774        {
3775                if(rx_chk_cnt < 4)
3776                {
3777                        //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3778                        return bStuck;
3779                }
3780                else
3781                {
3782                        rx_chk_cnt = 0;
3783                        //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3784                }
3785        }
3786        else
3787        {
3788                if(rx_chk_cnt < 8)
3789                {
3790                        //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3791                        return bStuck;
3792                }
3793                else
3794                {
3795                        rx_chk_cnt = 0;
3796                        //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3797                }
3798        }
3799        if(priv->RxCounter==RegRxCounter)
3800                bStuck = TRUE;
3801
3802        priv->RxCounter = RegRxCounter;
3803
3804        return bStuck;
3805}
3806
3807static RESET_TYPE RxCheckStuck(struct net_device *dev)
3808{
3809
3810        if(HalRxCheckStuck8190Pci(dev))
3811        {
3812                RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3813                return RESET_TYPE_SILENT;
3814        }
3815
3816        return RESET_TYPE_NORESET;
3817}
3818
3819static RESET_TYPE
3820rtl819x_ifcheck_resetornot(struct net_device *dev)
3821{
3822        struct r8192_priv *priv = ieee80211_priv(dev);
3823        RESET_TYPE      TxResetType = RESET_TYPE_NORESET;
3824        RESET_TYPE      RxResetType = RESET_TYPE_NORESET;
3825        RT_RF_POWER_STATE       rfState;
3826
3827        rfState = priv->ieee80211->eRFPowerState;
3828
3829        TxResetType = TxCheckStuck(dev);
3830#if 1
3831        if( rfState != eRfOff &&
3832                /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3833                (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3834        {
3835                // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3836                // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3837                // if driver is in firmware download failure status, driver should initialize RF in the following
3838                // silent reset procedure Emily, 2008.01.21
3839
3840                // Driver should not check RX stuck in IBSS mode because it is required to
3841                // set Check BSSID in order to send beacon, however, if check BSSID is
3842                // set, STA cannot hear any packet a all. Emily, 2008.04.12
3843                RxResetType = RxCheckStuck(dev);
3844        }
3845#endif
3846
3847        RT_TRACE(COMP_RESET,"%s(): TxResetType is %d, RxResetType is %d\n",__FUNCTION__,TxResetType,RxResetType);
3848        if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3849                return RESET_TYPE_NORMAL;
3850        else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT)
3851                return RESET_TYPE_SILENT;
3852        else
3853                return RESET_TYPE_NORESET;
3854
3855}
3856
3857
3858static void CamRestoreAllEntry(struct net_device *dev)
3859{
3860        u8 EntryId = 0;
3861        struct r8192_priv *priv = ieee80211_priv(dev);
3862        u8*     MacAddr = priv->ieee80211->current_network.bssid;
3863
3864        static u8       CAM_CONST_ADDR[4][6] = {
3865                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3866                {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3867                {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3868                {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3869        static u8       CAM_CONST_BROAD[] =
3870                {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3871
3872        RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3873
3874
3875        if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3876            (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3877        {
3878
3879                for(EntryId=0; EntryId<4; EntryId++)
3880                {
3881                        {
3882                                MacAddr = CAM_CONST_ADDR[EntryId];
3883                                setKey(dev,
3884                                                EntryId ,
3885                                                EntryId,
3886                                                priv->ieee80211->pairwise_key_type,
3887                                                MacAddr,
3888                                                0,
3889                                                NULL);
3890                        }
3891                }
3892
3893        }
3894        else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3895        {
3896
3897                {
3898                        if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3899                                setKey(dev,
3900                                                4,
3901                                                0,
3902                                                priv->ieee80211->pairwise_key_type,
3903                                                (u8*)dev->dev_addr,
3904                                                0,
3905                                                NULL);
3906                        else
3907                                setKey(dev,
3908                                                4,
3909                                                0,
3910                                                priv->ieee80211->pairwise_key_type,
3911                                                MacAddr,
3912                                                0,
3913                                                NULL);
3914                }
3915        }
3916        else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3917        {
3918
3919                {
3920                        if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3921                                setKey(dev,
3922                                                4,
3923                                                0,
3924                                                priv->ieee80211->pairwise_key_type,
3925                                                (u8*)dev->dev_addr,
3926                                                0,
3927                                                NULL);
3928                        else
3929                                setKey(dev,
3930                                                4,
3931                                                0,
3932                                                priv->ieee80211->pairwise_key_type,
3933                                                MacAddr,
3934                                                0,
3935                                                NULL);
3936                }
3937        }
3938
3939
3940
3941        if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3942        {
3943                MacAddr = CAM_CONST_BROAD;
3944                for(EntryId=1 ; EntryId<4 ; EntryId++)
3945                {
3946                        {
3947                                setKey(dev,
3948                                                EntryId,
3949                                                EntryId,
3950                                                priv->ieee80211->group_key_type,
3951                                                MacAddr,
3952                                                0,
3953                                                NULL);
3954                        }
3955                }
3956                if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3957                                setKey(dev,
3958                                                0,
3959                                                0,
3960                                                priv->ieee80211->group_key_type,
3961                                                CAM_CONST_ADDR[0],
3962                                                0,
3963                                                NULL);
3964        }
3965        else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3966        {
3967                MacAddr = CAM_CONST_BROAD;
3968                for(EntryId=1; EntryId<4 ; EntryId++)
3969                {
3970                        {
3971                                setKey(dev,
3972                                                EntryId ,
3973                                                EntryId,
3974                                                priv->ieee80211->group_key_type,
3975                                                MacAddr,
3976                                                0,
3977                                                NULL);
3978                        }
3979                }
3980
3981                if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3982                                setKey(dev,
3983                                                0 ,
3984                                                0,
3985                                                priv->ieee80211->group_key_type,
3986                                                CAM_CONST_ADDR[0],
3987                                                0,
3988                                                NULL);
3989        }
3990}
3991
3992void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3993int _rtl8192_up(struct net_device *dev);
3994
3995/*
3996 * This function is used to fix Tx/Rx stop bug temporarily.
3997 * This function will do "system reset" to NIC when Tx or Rx is stuck.
3998 * The method checking Tx/Rx stuck of this function is supported by FW,
3999 * which reports Tx and Rx counter to register 0x128 and 0x130.
4000 * */
4001static void rtl819x_ifsilentreset(struct net_device *dev)
4002{
4003        struct r8192_priv *priv = ieee80211_priv(dev);
4004        u8      reset_times = 0;
4005        int reset_status = 0;
4006        struct ieee80211_device *ieee = priv->ieee80211;
4007
4008
4009        // 2007.07.20. If we need to check CCK stop, please uncomment this line.
4010        //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
4011
4012        if(priv->ResetProgress==RESET_TYPE_NORESET)
4013        {
4014RESET_START:
4015
4016                RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
4017
4018                // Set the variable for reset.
4019                priv->ResetProgress = RESET_TYPE_SILENT;
4020//              rtl8192_close(dev);
4021#if 1
4022                down(&priv->wx_sem);
4023                if(priv->up == 0)
4024                {
4025                        RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
4026                        up(&priv->wx_sem);
4027                        return ;
4028                }
4029                priv->up = 0;
4030                RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
4031                if(!netif_queue_stopped(dev))
4032                        netif_stop_queue(dev);
4033
4034                dm_backup_dynamic_mechanism_state(dev);
4035
4036                rtl8192_irq_disable(dev);
4037                rtl8192_cancel_deferred_work(priv);
4038                deinit_hal_dm(dev);
4039                del_timer_sync(&priv->watch_dog_timer);
4040                ieee->sync_scan_hurryup = 1;
4041                if(ieee->state == IEEE80211_LINKED)
4042                {
4043                        down(&ieee->wx_sem);
4044                        printk("ieee->state is IEEE80211_LINKED\n");
4045                        ieee80211_stop_send_beacons(priv->ieee80211);
4046                        del_timer_sync(&ieee->associate_timer);
4047                        cancel_delayed_work(&ieee->associate_retry_wq);
4048                        ieee80211_stop_scan(ieee);
4049                        netif_carrier_off(dev);
4050                        up(&ieee->wx_sem);
4051                }
4052                else{
4053                        printk("ieee->state is NOT LINKED\n");
4054                        ieee80211_softmac_stop_protocol(priv->ieee80211);
4055                }
4056                rtl8192_rtx_disable(dev);
4057                up(&priv->wx_sem);
4058                RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
4059                RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
4060                reset_status = _rtl8192_up(dev);
4061
4062                RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
4063                if(reset_status == -1)
4064                {
4065                        if(reset_times < 3)
4066                        {
4067                                reset_times++;
4068                                goto RESET_START;
4069                        }
4070                        else
4071                        {
4072                                RT_TRACE(COMP_ERR," ERR!!! %s():  Reset Failed!!\n",__FUNCTION__);
4073                        }
4074                }
4075#endif
4076                ieee->is_silent_reset = 1;
4077#if 1
4078                EnableHWSecurityConfig8192(dev);
4079#if 1
4080                if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4081                {
4082                        ieee->set_chan(ieee->dev, ieee->current_network.channel);
4083
4084#if 1
4085                        queue_work(ieee->wq, &ieee->associate_complete_wq);
4086#endif
4087
4088                }
4089                else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
4090                {
4091                        ieee->set_chan(ieee->dev, ieee->current_network.channel);
4092                        ieee->link_change(ieee->dev);
4093
4094                //      notify_wx_assoc_event(ieee);
4095
4096                        ieee80211_start_send_beacons(ieee);
4097
4098                        if (ieee->data_hard_resume)
4099                                ieee->data_hard_resume(ieee->dev);
4100                        netif_carrier_on(ieee->dev);
4101                }
4102#endif
4103
4104                CamRestoreAllEntry(dev);
4105
4106                // Restore the previous setting for all dynamic mechanism
4107                dm_restore_dynamic_mechanism_state(dev);
4108
4109                priv->ResetProgress = RESET_TYPE_NORESET;
4110                priv->reset_count++;
4111
4112                priv->bForcedSilentReset =false;
4113                priv->bResetInProgress = false;
4114
4115                // For test --> force write UFWP.
4116                write_nic_byte(dev, UFWP, 1);
4117                RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4118#endif
4119        }
4120}
4121
4122#ifdef ENABLE_IPS
4123void InactivePsWorkItemCallback(struct net_device *dev)
4124{
4125        struct r8192_priv *priv = ieee80211_priv(dev);
4126        PRT_POWER_SAVE_CONTROL  pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4127        //u8                                                    index = 0;
4128
4129        RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() ---------> \n");
4130        //
4131        // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
4132        // is really scheduled.
4133        // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
4134        // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
4135        // blocks the IPS procedure of switching RF.
4136        // By Bruce, 2007-12-25.
4137        //
4138        pPSC->bSwRfProcessing = TRUE;
4139
4140        RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", \
4141                        pPSC->eInactivePowerState == eRfOff?"OFF":"ON");
4142
4143
4144        MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS);
4145
4146        //
4147        // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
4148        //
4149        pPSC->bSwRfProcessing = FALSE;
4150        RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <--------- \n");
4151}
4152
4153//
4154//      Description:
4155//              Enter the inactive power save mode. RF will be off
4156//      2007.08.17, by shien chang.
4157//
4158void
4159IPSEnter(struct net_device *dev)
4160{
4161        struct r8192_priv *priv = ieee80211_priv(dev);
4162        PRT_POWER_SAVE_CONTROL          pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4163        RT_RF_POWER_STATE                       rtState;
4164
4165        if (pPSC->bInactivePs)
4166        {
4167                rtState = priv->ieee80211->eRFPowerState;
4168                //
4169                // Added by Bruce, 2007-12-25.
4170                // Do not enter IPS in the following conditions:
4171                // (1) RF is already OFF or Sleep
4172                // (2) bSwRfProcessing (indicates the IPS is still under going)
4173                // (3) Connectted (only disconnected can trigger IPS)
4174                // (4) IBSS (send Beacon)
4175                // (5) AP mode (send Beacon)
4176                //
4177                if (rtState == eRfOn && !pPSC->bSwRfProcessing
4178                        && (priv->ieee80211->state != IEEE80211_LINKED) )
4179                {
4180                        RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n");
4181                        pPSC->eInactivePowerState = eRfOff;
4182//                      queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4183                        InactivePsWorkItemCallback(dev);
4184                }
4185        }
4186}
4187
4188//
4189//      Description:
4190//              Leave the inactive power save mode, RF will be on.
4191//      2007.08.17, by shien chang.
4192//
4193void
4194IPSLeave(struct net_device *dev)
4195{
4196        struct r8192_priv *priv = ieee80211_priv(dev);
4197        PRT_POWER_SAVE_CONTROL  pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
4198        RT_RF_POWER_STATE       rtState;
4199
4200        if (pPSC->bInactivePs)
4201        {
4202                rtState = priv->ieee80211->eRFPowerState;
4203                if (rtState != eRfOn  && !pPSC->bSwRfProcessing && priv->ieee80211->RfOffReason <= RF_CHANGE_BY_IPS)
4204                {
4205                        RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n");
4206                        pPSC->eInactivePowerState = eRfOn;
4207//                      queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem));
4208                        InactivePsWorkItemCallback(dev);
4209                }
4210        }
4211}
4212#endif
4213
4214static void rtl819x_update_rxcounts(
4215        struct r8192_priv *priv,
4216        u32* TotalRxBcnNum,
4217        u32* TotalRxDataNum
4218)
4219{
4220        u16                     SlotIndex;
4221        u8                      i;
4222
4223        *TotalRxBcnNum = 0;
4224        *TotalRxDataNum = 0;
4225
4226        SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4227        priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4228        priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4229        for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4230                *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4231                *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4232        }
4233}
4234
4235
4236void rtl819x_watchdog_wqcallback(struct work_struct *work)
4237{
4238        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4239       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4240       struct net_device *dev = priv->ieee80211->dev;
4241        struct ieee80211_device* ieee = priv->ieee80211;
4242        RESET_TYPE      ResetType = RESET_TYPE_NORESET;
4243        static u8       check_reset_cnt=0;
4244        unsigned long flags;
4245        bool bBusyTraffic = false;
4246        static u8 last_time = 0;
4247        if(!priv->up)
4248                return;
4249        hal_dm_watchdog(dev);
4250#ifdef ENABLE_IPS
4251//      printk("watch_dog ENABLE_IPS\n");
4252        if(ieee->actscanning == false){
4253                if((ieee->iw_mode != IW_MODE_ADHOC) && (ieee->state == IEEE80211_NOLINK) && (ieee->beinretry == false) && (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key){
4254                        if(ieee->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){
4255                                printk("====================>haha:IPSEnter()\n");
4256                                IPSEnter(dev);
4257                                //ieee80211_stop_scan(priv->ieee80211);
4258                        }
4259                }
4260        }
4261#endif
4262        {//to get busy traffic condition
4263                if(ieee->state == IEEE80211_LINKED)
4264                {
4265                        if(     ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4266                                ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4267                                bBusyTraffic = true;
4268                        }
4269
4270                }
4271                ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4272                ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4273                ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4274        }
4275
4276
4277        //added by amy for AP roaming
4278        if (1)
4279        {
4280                if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
4281                {
4282                        u32     TotalRxBcnNum = 0;
4283                        u32     TotalRxDataNum = 0;
4284
4285                        rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4286                        if((TotalRxBcnNum+TotalRxDataNum) == 0)
4287                        {
4288                                if( ieee->eRFPowerState == eRfOff)
4289                                        RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4290                                printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4291                //              Dot11d_Reset(dev);
4292                                ieee->state = IEEE80211_ASSOCIATING;
4293                                notify_wx_assoc_event(priv->ieee80211);
4294                                RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4295                                ieee->is_roaming = true;
4296                                ieee->is_set_key = false;
4297                             ieee->link_change(dev);
4298                                queue_work(ieee->wq, &ieee->associate_procedure_wq);
4299                        }
4300                }
4301              ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
4302              ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
4303
4304        }
4305        //check if reset the driver
4306        spin_lock_irqsave(&priv->tx_lock,flags);
4307        if(check_reset_cnt++ >= 3 && !ieee->is_roaming && (last_time != 1))
4308        {
4309                ResetType = rtl819x_ifcheck_resetornot(dev);
4310                check_reset_cnt = 3;
4311                //DbgPrint("Start to check silent reset\n");
4312        }
4313        spin_unlock_irqrestore(&priv->tx_lock,flags);
4314        if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL)
4315        {
4316                priv->ResetProgress = RESET_TYPE_NORMAL;
4317                RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__);
4318                return;
4319        }
4320        /* disable silent reset temply 2008.9.11*/
4321#if 1
4322        if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo
4323        {
4324                last_time = 1;
4325                rtl819x_ifsilentreset(dev);
4326        }
4327        else
4328                last_time = 0;
4329#endif
4330        priv->force_reset = false;
4331        priv->bForcedSilentReset = false;
4332        priv->bResetInProgress = false;
4333        RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4334
4335}
4336
4337void watch_dog_timer_callback(unsigned long data)
4338{
4339        struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4340        queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0);
4341        mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4342
4343}
4344int _rtl8192_up(struct net_device *dev)
4345{
4346        struct r8192_priv *priv = ieee80211_priv(dev);
4347        //int i;
4348        RT_STATUS init_status = RT_STATUS_SUCCESS;
4349        priv->up=1;
4350        priv->ieee80211->ieee_up=1;
4351        RT_TRACE(COMP_INIT, "Bringing up iface");
4352
4353        init_status = rtl8192_adapter_start(dev);
4354        if(init_status != RT_STATUS_SUCCESS)
4355        {
4356                RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__);
4357                return -1;
4358        }
4359        RT_TRACE(COMP_INIT, "start adapter finished\n");
4360#ifdef RTL8192E
4361        if(priv->ieee80211->eRFPowerState!=eRfOn)
4362                MgntActSet_RF_State(dev, eRfOn, priv->ieee80211->RfOffReason);
4363#endif
4364        if(priv->ieee80211->state != IEEE80211_LINKED)
4365        ieee80211_softmac_start_protocol(priv->ieee80211);
4366        ieee80211_reset_queue(priv->ieee80211);
4367        watch_dog_timer_callback((unsigned long) dev);
4368        if(!netif_queue_stopped(dev))
4369                netif_start_queue(dev);
4370        else
4371                netif_wake_queue(dev);
4372
4373        return 0;
4374}
4375
4376
4377static int rtl8192_open(struct net_device *dev)
4378{
4379        struct r8192_priv *priv = ieee80211_priv(dev);
4380        int ret;
4381
4382        down(&priv->wx_sem);
4383        ret = rtl8192_up(dev);
4384        up(&priv->wx_sem);
4385        return ret;
4386
4387}
4388
4389
4390int rtl8192_up(struct net_device *dev)
4391{
4392        struct r8192_priv *priv = ieee80211_priv(dev);
4393
4394        if (priv->up == 1) return -1;
4395
4396        return _rtl8192_up(dev);
4397}
4398
4399
4400static int rtl8192_close(struct net_device *dev)
4401{
4402        struct r8192_priv *priv = ieee80211_priv(dev);
4403        int ret;
4404
4405        down(&priv->wx_sem);
4406
4407        ret = rtl8192_down(dev);
4408
4409        up(&priv->wx_sem);
4410
4411        return ret;
4412
4413}
4414
4415int rtl8192_down(struct net_device *dev)
4416{
4417        struct r8192_priv *priv = ieee80211_priv(dev);
4418//      int i;
4419#if 0
4420        u8      ucRegRead;
4421        u32     ulRegRead;
4422#endif
4423        if (priv->up == 0) return -1;
4424
4425        priv->up=0;
4426        priv->ieee80211->ieee_up = 0;
4427        RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4428/* FIXME */
4429        if (!netif_queue_stopped(dev))
4430                netif_stop_queue(dev);
4431
4432        rtl8192_irq_disable(dev);
4433#if 0
4434        if(!priv->ieee80211->bSupportRemoteWakeUp) {
4435                MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4436                // 2006.11.30. System reset bit
4437                ulRegRead = read_nic_dword(dev, CPU_GEN);
4438                ulRegRead|=CPU_GEN_SYSTEM_RESET;
4439                write_nic_dword(dev, CPU_GEN, ulRegRead);
4440        } else {
4441                //2008.06.03 for WOL
4442                write_nic_dword(dev, WFCRC0, 0xffffffff);
4443                write_nic_dword(dev, WFCRC1, 0xffffffff);
4444                write_nic_dword(dev, WFCRC2, 0xffffffff);
4445#ifdef RTL8190P
4446                //GPIO 0 = TRUE
4447                ucRegRead = read_nic_byte(dev, GPO);
4448                ucRegRead |= BIT0;
4449                write_nic_byte(dev, GPO, ucRegRead);
4450#endif
4451                //Write PMR register
4452                write_nic_byte(dev, PMR, 0x5);
4453                //Disable tx, enanble rx
4454                write_nic_byte(dev, MacBlkCtrl, 0xa);
4455        }
4456#endif
4457//      flush_scheduled_work();
4458        rtl8192_cancel_deferred_work(priv);
4459        deinit_hal_dm(dev);
4460        del_timer_sync(&priv->watch_dog_timer);
4461
4462        ieee80211_softmac_stop_protocol(priv->ieee80211);
4463#ifdef ENABLE_IPS
4464        MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT);
4465#endif
4466        rtl8192_rtx_disable(dev);
4467        memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4468
4469        RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4470
4471                return 0;
4472}
4473
4474
4475void rtl8192_commit(struct net_device *dev)
4476{
4477        struct r8192_priv *priv = ieee80211_priv(dev);
4478
4479        if (priv->up == 0) return ;
4480
4481
4482        ieee80211_softmac_stop_protocol(priv->ieee80211);
4483
4484        rtl8192_irq_disable(dev);
4485        rtl8192_rtx_disable(dev);
4486        _rtl8192_up(dev);
4487}
4488
4489void rtl8192_restart(struct work_struct *work)
4490{
4491        struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4492        struct net_device *dev = priv->ieee80211->dev;
4493
4494        down(&priv->wx_sem);
4495
4496        rtl8192_commit(dev);
4497
4498        up(&priv->wx_sem);
4499}
4500
4501static void r8192_set_multicast(struct net_device *dev)
4502{
4503        struct r8192_priv *priv = ieee80211_priv(dev);
4504        short promisc;
4505
4506        //down(&priv->wx_sem);
4507
4508        /* FIXME FIXME */
4509
4510        promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4511
4512        if (promisc != priv->promisc) {
4513                ;
4514        //      rtl8192_commit(dev);
4515        }
4516
4517        priv->promisc = promisc;
4518
4519        //schedule_work(&priv->reset_wq);
4520        //up(&priv->wx_sem);
4521}
4522
4523
4524static int r8192_set_mac_adr(struct net_device *dev, void *mac)
4525{
4526        struct r8192_priv *priv = ieee80211_priv(dev);
4527        struct sockaddr *addr = mac;
4528
4529        down(&priv->wx_sem);
4530
4531        memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4532
4533        schedule_work(&priv->reset_wq);
4534        up(&priv->wx_sem);
4535
4536        return 0;
4537}
4538
4539/* based on ipw2200 driver */
4540static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4541{
4542        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4543        struct iwreq *wrq = (struct iwreq *)rq;
4544        int ret=-1;
4545        struct ieee80211_device *ieee = priv->ieee80211;
4546        u32 key[4];
4547        u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4548        struct iw_point *p = &wrq->u.data;
4549        struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4550
4551        down(&priv->wx_sem);
4552
4553
4554     if (p->length < sizeof(struct ieee_param) || !p->pointer){
4555             ret = -EINVAL;
4556             goto out;
4557     }
4558
4559     ipw = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
4560     if (ipw == NULL){
4561             ret = -ENOMEM;
4562             goto out;
4563     }
4564     if (copy_from_user(ipw, p->pointer, p->length)) {
4565            kfree(ipw);
4566            ret = -EFAULT;
4567            goto out;
4568     }
4569
4570        switch (cmd) {
4571            case RTL_IOCTL_WPA_SUPPLICANT:
4572                //parse here for HW security
4573                        if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4574                        {
4575                                if (ipw->u.crypt.set_tx)
4576                                {
4577                                        if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4578                                                ieee->pairwise_key_type = KEY_TYPE_CCMP;
4579                                        else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4580                                                ieee->pairwise_key_type = KEY_TYPE_TKIP;
4581                                        else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4582                                        {
4583                                                if (ipw->u.crypt.key_len == 13)
4584                                                        ieee->pairwise_key_type = KEY_TYPE_WEP104;
4585                                                else if (ipw->u.crypt.key_len == 5)
4586                                                        ieee->pairwise_key_type = KEY_TYPE_WEP40;
4587                                        }
4588                                        else
4589                                                ieee->pairwise_key_type = KEY_TYPE_NA;
4590
4591                                        if (ieee->pairwise_key_type)
4592                                        {
4593                                                memcpy((u8*)key, ipw->u.crypt.key, 16);
4594                                                EnableHWSecurityConfig8192(dev);
4595                                        //we fill both index entry and 4th entry for pairwise key as in IPW interface, adhoc will only get here, so we need index entry for its default key serching!
4596                                        //added by WB.
4597                                                setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4598                                                if (ieee->auth_mode != 2)  //LEAP WEP will never set this.
4599                                                setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4600                                        }
4601                                        if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){
4602                                                        write_nic_byte(dev, 0x173, 1); //fix aes bug
4603                                                }
4604
4605                                }
4606                                else //if (ipw->u.crypt.idx) //group key use idx > 0
4607                                {
4608                                        memcpy((u8*)key, ipw->u.crypt.key, 16);
4609                                        if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4610                                                ieee->group_key_type= KEY_TYPE_CCMP;
4611                                        else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4612                                                ieee->group_key_type = KEY_TYPE_TKIP;
4613                                        else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4614                                        {
4615                                                if (ipw->u.crypt.key_len == 13)
4616                                                        ieee->group_key_type = KEY_TYPE_WEP104;
4617                                                else if (ipw->u.crypt.key_len == 5)
4618                                                        ieee->group_key_type = KEY_TYPE_WEP40;
4619                                        }
4620                                        else
4621                                                ieee->group_key_type = KEY_TYPE_NA;
4622
4623                                        if (ieee->group_key_type)
4624                                        {
4625                                                        setKey( dev,
4626                                                                ipw->u.crypt.idx,
4627                                                                ipw->u.crypt.idx,               //KeyIndex
4628                                                                ieee->group_key_type,   //KeyType
4629                                                                broadcast_addr, //MacAddr
4630                                                                0,              //DefaultKey
4631                                                                key);           //KeyContent
4632                                        }
4633                                }
4634                        }
4635#ifdef JOHN_DEBUG
4636                //john's test 0711
4637        {
4638                int i;
4639                printk("@@ wrq->u pointer = ");
4640                for(i=0;i<wrq->u.data.length;i++){
4641                        if(i%10==0) printk("\n");
4642                        printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4643                }
4644                printk("\n");
4645        }
4646#endif /*JOHN_DEBUG*/
4647                ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4648                break;
4649
4650            default:
4651                ret = -EOPNOTSUPP;
4652                break;
4653        }
4654
4655        kfree(ipw);
4656out:
4657        up(&priv->wx_sem);
4658
4659        return ret;
4660}
4661
4662static u8 HwRateToMRate90(bool bIsHT, u8 rate)
4663{
4664        u8  ret_rate = 0x02;
4665
4666        if(!bIsHT) {
4667                switch(rate) {
4668                        case DESC90_RATE1M:   ret_rate = MGN_1M;         break;
4669                        case DESC90_RATE2M:   ret_rate = MGN_2M;         break;
4670                        case DESC90_RATE5_5M: ret_rate = MGN_5_5M;       break;
4671                        case DESC90_RATE11M:  ret_rate = MGN_11M;        break;
4672                        case DESC90_RATE6M:   ret_rate = MGN_6M;         break;
4673                        case DESC90_RATE9M:   ret_rate = MGN_9M;         break;
4674                        case DESC90_RATE12M:  ret_rate = MGN_12M;        break;
4675                        case DESC90_RATE18M:  ret_rate = MGN_18M;        break;
4676                        case DESC90_RATE24M:  ret_rate = MGN_24M;        break;
4677                        case DESC90_RATE36M:  ret_rate = MGN_36M;        break;
4678                        case DESC90_RATE48M:  ret_rate = MGN_48M;        break;
4679                        case DESC90_RATE54M:  ret_rate = MGN_54M;        break;
4680
4681                        default:
4682                                              RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4683                                              break;
4684                }
4685
4686        } else {
4687                switch(rate) {
4688                        case DESC90_RATEMCS0:   ret_rate = MGN_MCS0;    break;
4689                        case DESC90_RATEMCS1:   ret_rate = MGN_MCS1;    break;
4690                        case DESC90_RATEMCS2:   ret_rate = MGN_MCS2;    break;
4691                        case DESC90_RATEMCS3:   ret_rate = MGN_MCS3;    break;
4692                        case DESC90_RATEMCS4:   ret_rate = MGN_MCS4;    break;
4693                        case DESC90_RATEMCS5:   ret_rate = MGN_MCS5;    break;
4694                        case DESC90_RATEMCS6:   ret_rate = MGN_MCS6;    break;
4695                        case DESC90_RATEMCS7:   ret_rate = MGN_MCS7;    break;
4696                        case DESC90_RATEMCS8:   ret_rate = MGN_MCS8;    break;
4697                        case DESC90_RATEMCS9:   ret_rate = MGN_MCS9;    break;
4698                        case DESC90_RATEMCS10:  ret_rate = MGN_MCS10;   break;
4699                        case DESC90_RATEMCS11:  ret_rate = MGN_MCS11;   break;
4700                        case DESC90_RATEMCS12:  ret_rate = MGN_MCS12;   break;
4701                        case DESC90_RATEMCS13:  ret_rate = MGN_MCS13;   break;
4702                        case DESC90_RATEMCS14:  ret_rate = MGN_MCS14;   break;
4703                        case DESC90_RATEMCS15:  ret_rate = MGN_MCS15;   break;
4704                        case DESC90_RATEMCS32:  ret_rate = (0x80|0x20); break;
4705
4706                        default:
4707                                                RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4708                                                break;
4709                }
4710        }
4711
4712        return ret_rate;
4713}
4714
4715/**
4716 * Function:     UpdateRxPktTimeStamp
4717 * Overview:     Recored down the TSF time stamp when receiving a packet
4718 *
4719 * Input:
4720 *       PADAPTER        Adapter
4721 *       PRT_RFD         pRfd,
4722 *
4723 * Output:
4724 *       PRT_RFD         pRfd
4725 *                               (pRfd->Status.TimeStampHigh is updated)
4726 *                               (pRfd->Status.TimeStampLow is updated)
4727 * Return:
4728 *               None
4729 */
4730static void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4731{
4732        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4733
4734        if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4735                stats->mac_time[0] = priv->LastRxDescTSFLow;
4736                stats->mac_time[1] = priv->LastRxDescTSFHigh;
4737        } else {
4738                priv->LastRxDescTSFLow = stats->mac_time[0];
4739                priv->LastRxDescTSFHigh = stats->mac_time[1];
4740        }
4741}
4742
4743static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index.
4744{
4745        long    signal_power; // in dBm.
4746
4747        // Translate to dBm (x=0.5y-95).
4748        signal_power = (long)((signal_strength_index + 1) >> 1);
4749        signal_power -= 95;
4750
4751        return signal_power;
4752}
4753
4754//
4755//      Description:
4756//              Update Rx signal related information in the packet reeived
4757//              to RxStats. User application can query RxStats to realize
4758//              current Rx signal status.
4759//
4760//      Assumption:
4761//              In normal operation, user only care about the information of the BSS
4762//              and we shall invoke this function if the packet received is from the BSS.
4763//
4764static void
4765rtl819x_update_rxsignalstatistics8190pci(
4766        struct r8192_priv * priv,
4767        struct ieee80211_rx_stats * pprevious_stats
4768        )
4769{
4770        int weighting = 0;
4771
4772        //2 <ToDo> Update Rx Statistics (such as signal strength and signal quality).
4773
4774        // Initila state
4775        if(priv->stats.recv_signal_power == 0)
4776                priv->stats.recv_signal_power = pprevious_stats->RecvSignalPower;
4777
4778        // To avoid the past result restricting the statistics sensitivity, weight the current power (5/6) to speed up the
4779        // reaction of smoothed Signal Power.
4780        if(pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power)
4781                weighting = 5;
4782        else if(pprevious_stats->RecvSignalPower < priv->stats.recv_signal_power)
4783                weighting = (-5);
4784        //
4785        // We need more correct power of received packets and the  "SignalStrength" of RxStats have been beautified or translated,
4786        // so we record the correct power in Dbm here. By Bruce, 2008-03-07.
4787        //
4788        priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + pprevious_stats->RecvSignalPower + weighting) / 6;
4789}
4790
4791static void
4792rtl8190_process_cck_rxpathsel(
4793        struct r8192_priv * priv,
4794        struct ieee80211_rx_stats * pprevious_stats
4795        )
4796{
4797#ifdef RTL8190P //Only 90P 2T4R need to check
4798        char                            last_cck_adc_pwdb[4]={0,0,0,0};
4799        u8                              i;
4800//cosa add for Rx path selection
4801                if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable)
4802                {
4803                        if(pprevious_stats->bIsCCK &&
4804                                (pprevious_stats->bPacketToSelf ||pprevious_stats->bPacketBeacon))
4805                        {
4806                                /* record the cck adc_pwdb to the sliding window. */
4807                                if(priv->stats.cck_adc_pwdb.TotalNum++ >= PHY_RSSI_SLID_WIN_MAX)
4808                                {
4809                                        priv->stats.cck_adc_pwdb.TotalNum = PHY_RSSI_SLID_WIN_MAX;
4810                                        for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4811                                        {
4812                                                last_cck_adc_pwdb[i] = priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index];
4813                                                priv->stats.cck_adc_pwdb.TotalVal[i] -= last_cck_adc_pwdb[i];
4814                                        }
4815                                }
4816                                for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4817                                {
4818                                        priv->stats.cck_adc_pwdb.TotalVal[i] += pprevious_stats->cck_adc_pwdb[i];
4819                                        priv->stats.cck_adc_pwdb.elements[i][priv->stats.cck_adc_pwdb.index] = pprevious_stats->cck_adc_pwdb[i];
4820                                }
4821                                priv->stats.cck_adc_pwdb.index++;
4822                                if(priv->stats.cck_adc_pwdb.index >= PHY_RSSI_SLID_WIN_MAX)
4823                                        priv->stats.cck_adc_pwdb.index = 0;
4824
4825                                for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4826                                {
4827                                        DM_RxPathSelTable.cck_pwdb_sta[i] = priv->stats.cck_adc_pwdb.TotalVal[i]/priv->stats.cck_adc_pwdb.TotalNum;
4828                                }
4829
4830                                for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
4831                                {
4832                                        if(pprevious_stats->cck_adc_pwdb[i]  > (char)priv->undecorated_smoothed_cck_adc_pwdb[i])
4833                                        {
4834                                                priv->undecorated_smoothed_cck_adc_pwdb[i] =
4835                                                        ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
4836                                                        (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
4837                                                priv->undecorated_smoothed_cck_adc_pwdb[i] = priv->undecorated_smoothed_cck_adc_pwdb[i] + 1;
4838                                        }
4839                                        else
4840                                        {
4841                                                priv->undecorated_smoothed_cck_adc_pwdb[i] =
4842                                                        ( (priv->undecorated_smoothed_cck_adc_pwdb[i]*(Rx_Smooth_Factor-1)) +
4843                                                        (pprevious_stats->cck_adc_pwdb[i])) /(Rx_Smooth_Factor);
4844                                        }
4845                                }
4846                        }
4847                }
4848#endif
4849}
4850
4851
4852/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4853        be a local static. Otherwise, it may increase when we return from S3/S4. The
4854        value will be kept in memory or disk. We must delcare the value in adapter
4855        and it will be reinitialized when return from S3/S4. */
4856static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4857{
4858        bool bcheck = false;
4859        u8      rfpath;
4860        u32 nspatial_stream, tmp_val;
4861        //u8    i;
4862        static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4863        static u32 slide_evm_index=0, slide_evm_statistics=0;
4864        static u32 last_rssi=0, last_evm=0;
4865        //cosa add for rx path selection
4866//      static long slide_cck_adc_pwdb_index=0, slide_cck_adc_pwdb_statistics=0;
4867//      static char last_cck_adc_pwdb[4]={0,0,0,0};
4868        //cosa add for beacon rssi smoothing
4869        static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4870        static u32 last_beacon_adc_pwdb=0;
4871
4872        struct ieee80211_hdr_3addr *hdr;
4873        u16 sc ;
4874        unsigned int frag,seq;
4875        hdr = (struct ieee80211_hdr_3addr *)buffer;
4876        sc = le16_to_cpu(hdr->seq_ctl);
4877        frag = WLAN_GET_SEQ_FRAG(sc);
4878        seq = WLAN_GET_SEQ_SEQ(sc);
4879        //cosa add 04292008 to record the sequence number
4880        pcurrent_stats->Seq_Num = seq;
4881        //
4882        // Check whether we should take the previous packet into accounting
4883        //
4884        if(!pprevious_stats->bIsAMPDU)
4885        {
4886                // if previous packet is not aggregated packet
4887                bcheck = true;
4888        }else
4889        {
4890//remve for that we don't use AMPDU to calculate PWDB,because the reported PWDB of some AP is fault.
4891#if 0
4892                // if previous packet is aggregated packet, and current packet
4893                //      (1) is not AMPDU
4894                //      (2) is the first packet of one AMPDU
4895                // that means the previous packet is the last one aggregated packet
4896                if( !pcurrent_stats->bIsAMPDU || pcurrent_stats->bFirstMPDU)
4897                        bcheck = true;
4898#endif
4899        }
4900
4901        if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4902        {
4903                slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4904                last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4905                priv->stats.slide_rssi_total -= last_rssi;
4906        }
4907        priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4908
4909        priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4910        if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4911                slide_rssi_index = 0;
4912
4913        // <1> Showed on UI for user, in dbm
4914        tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4915        priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4916        pcurrent_stats->rssi = priv->stats.signal_strength;
4917        //
4918        // If the previous packet does not match the criteria, neglect it
4919        //
4920        if(!pprevious_stats->bPacketMatchBSSID)
4921        {
4922                if(!pprevious_stats->bToSelfBA)
4923                        return;
4924        }
4925
4926        if(!bcheck)
4927                return;
4928
4929        rtl8190_process_cck_rxpathsel(priv,pprevious_stats);
4930
4931        //
4932        // Check RSSI
4933        //
4934        priv->stats.num_process_phyinfo++;
4935#if 0
4936        /* record the general signal strength to the sliding window. */
4937        if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4938        {
4939                slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4940                last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4941                priv->stats.slide_rssi_total -= last_rssi;
4942        }
4943        priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4944
4945        priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4946        if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4947                slide_rssi_index = 0;
4948
4949        // <1> Showed on UI for user, in dbm
4950        tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4951        priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4952
4953#endif
4954        // <2> Showed on UI for engineering
4955        // hardware does not provide rssi information for each rf path in CCK
4956        if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf)
4957        {
4958                for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++)
4959                {
4960                        if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4961                                continue;
4962                        RT_TRACE(COMP_DBG,"Jacken -> pPreviousstats->RxMIMOSignalStrength[rfpath]  = %d \n" ,pprevious_stats->RxMIMOSignalStrength[rfpath] );
4963                        //Fixed by Jacken 2008-03-20
4964                        if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4965                        {
4966                                priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4967                                //DbgPrint("MIMO RSSI initialize \n");
4968                        }
4969                        if(pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath])
4970                        {
4971                                priv->stats.rx_rssi_percentage[rfpath] =
4972                                        ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4973                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4974                                priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
4975                        }
4976                        else
4977                        {
4978                                priv->stats.rx_rssi_percentage[rfpath] =
4979                                        ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4980                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4981                        }
4982                        RT_TRACE(COMP_DBG,"Jacken -> priv->RxStats.RxRSSIPercentage[rfPath]  = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4983                }
4984        }
4985
4986
4987        //
4988        // Check PWDB.
4989        //
4990        //cosa add for beacon rssi smoothing by average.
4991        if(pprevious_stats->bPacketBeacon)
4992        {
4993                /* record the beacon pwdb to the sliding window. */
4994                if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4995                {
4996                        slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4997                        last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4998                        priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4999                        //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
5000                        //      slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
5001                }
5002                priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
5003                priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
5004                //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
5005                slide_beacon_adc_pwdb_index++;
5006                if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
5007                        slide_beacon_adc_pwdb_index = 0;
5008                pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
5009                if(pprevious_stats->RxPWDBAll >= 3)
5010                        pprevious_stats->RxPWDBAll -= 3;
5011        }
5012
5013        RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
5014                                pprevious_stats->bIsCCK? "CCK": "OFDM",
5015                                pprevious_stats->RxPWDBAll);
5016
5017        if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5018        {
5019                if(priv->undecorated_smoothed_pwdb < 0) // initialize
5020                {
5021                        priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
5022                        //DbgPrint("First pwdb initialize \n");
5023                }
5024#if 1
5025                if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
5026                {
5027                        priv->undecorated_smoothed_pwdb =
5028                                        ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5029                                        (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5030                        priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
5031                }
5032                else
5033                {
5034                        priv->undecorated_smoothed_pwdb =
5035                                        ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
5036                                        (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
5037                }
5038#else
5039                //Fixed by Jacken 2008-03-20
5040                if(pPreviousRfd->Status.RxPWDBAll > (u32)pHalData->UndecoratedSmoothedPWDB)
5041                {
5042                        pHalData->UndecoratedSmoothedPWDB =
5043                                        ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5044                        pHalData->UndecoratedSmoothedPWDB = pHalData->UndecoratedSmoothedPWDB + 1;
5045                }
5046                else
5047                {
5048                        pHalData->UndecoratedSmoothedPWDB =
5049                                        ( ((pHalData->UndecoratedSmoothedPWDB)* 5) + (pPreviousRfd->Status.RxPWDBAll)) / 6;
5050                }
5051#endif
5052                rtl819x_update_rxsignalstatistics8190pci(priv,pprevious_stats);
5053        }
5054
5055        //
5056        // Check EVM
5057        //
5058        /* record the general EVM to the sliding window. */
5059        if(pprevious_stats->SignalQuality == 0)
5060        {
5061        }
5062        else
5063        {
5064                if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
5065                        if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
5066                                slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
5067                                last_evm = priv->stats.slide_evm[slide_evm_index];
5068                                priv->stats.slide_evm_total -= last_evm;
5069                        }
5070
5071                        priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
5072
5073                        priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
5074                        if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
5075                                slide_evm_index = 0;
5076
5077                        // <1> Showed on UI for user, in percentage.
5078                        tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
5079                        priv->stats.signal_quality = tmp_val;
5080                        //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
5081                        priv->stats.last_signal_strength_inpercent = tmp_val;
5082                }
5083
5084                // <2> Showed on UI for engineering
5085                if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
5086                {
5087                        for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
5088                        {
5089                                if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
5090                                {
5091                                        if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
5092                                        {
5093                                                priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
5094                                        }
5095                                        priv->stats.rx_evm_percentage[nspatial_stream] =
5096                                                ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
5097                                                (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
5098                                }
5099                        }
5100                }
5101        }
5102
5103}
5104
5105/*-----------------------------------------------------------------------------
5106 * Function:    rtl819x_query_rxpwrpercentage()
5107 *
5108 * Overview:
5109 *
5110 * Input:               char            antpower
5111 *
5112 * Output:              NONE
5113 *
5114 * Return:              0-100 percentage
5115 *
5116 * Revised History:
5117 *      When            Who     Remark
5118 *      05/26/2008      amy     Create Version 0 porting from windows code.
5119 *
5120 *---------------------------------------------------------------------------*/
5121static u8 rtl819x_query_rxpwrpercentage(
5122        char            antpower
5123        )
5124{
5125        if ((antpower <= -100) || (antpower >= 20))
5126        {
5127                return  0;
5128        }
5129        else if (antpower >= 0)
5130        {
5131                return  100;
5132        }
5133        else
5134        {
5135                return  (100+antpower);
5136        }
5137
5138}       /* QueryRxPwrPercentage */
5139
5140static u8
5141rtl819x_evm_dbtopercentage(
5142        char value
5143        )
5144{
5145        char ret_val;
5146
5147        ret_val = value;
5148
5149        if(ret_val >= 0)
5150                ret_val = 0;
5151        if(ret_val <= -33)
5152                ret_val = -33;
5153        ret_val = 0 - ret_val;
5154        ret_val*=3;
5155        if(ret_val == 99)
5156                ret_val = 100;
5157        return(ret_val);
5158}
5159
5160//
5161//      Description:
5162//      We want good-looking for signal strength/quality
5163//      2007/7/19 01:09, by cosa.
5164//
5165static long rtl819x_signal_scale_mapping(long currsig)
5166{
5167        long retsig;
5168
5169        // Step 1. Scale mapping.
5170        if(currsig >= 61 && currsig <= 100)
5171        {
5172                retsig = 90 + ((currsig - 60) / 4);
5173        }
5174        else if(currsig >= 41 && currsig <= 60)
5175        {
5176                retsig = 78 + ((currsig - 40) / 2);
5177        }
5178        else if(currsig >= 31 && currsig <= 40)
5179        {
5180                retsig = 66 + (currsig - 30);
5181        }
5182        else if(currsig >= 21 && currsig <= 30)
5183        {
5184                retsig = 54 + (currsig - 20);
5185        }
5186        else if(currsig >= 5 && currsig <= 20)
5187        {
5188                retsig = 42 + (((currsig - 5) * 2) / 3);
5189        }
5190        else if(currsig == 4)
5191        {
5192                retsig = 36;
5193        }
5194        else if(currsig == 3)
5195        {
5196                retsig = 27;
5197        }
5198        else if(currsig == 2)
5199        {
5200                retsig = 18;
5201        }
5202        else if(currsig == 1)
5203        {
5204                retsig = 9;
5205        }
5206        else
5207        {
5208                retsig = currsig;
5209        }
5210
5211        return retsig;
5212}
5213
5214static void rtl8192_query_rxphystatus(
5215        struct r8192_priv * priv,
5216        struct ieee80211_rx_stats * pstats,
5217        prx_desc_819x_pci  pdesc,
5218        prx_fwinfo_819x_pci   pdrvinfo,
5219        struct ieee80211_rx_stats * precord_stats,
5220        bool bpacket_match_bssid,
5221        bool bpacket_toself,
5222        bool bPacketBeacon,
5223        bool bToSelfBA
5224        )
5225{
5226        //PRT_RFD_STATUS                pRtRfdStatus = &(pRfd->Status);
5227        phy_sts_ofdm_819xpci_t* pofdm_buf;
5228        phy_sts_cck_819xpci_t   *       pcck_buf;
5229        phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
5230        u8                              *prxpkt;
5231        u8                              i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
5232        char                            rx_pwr[4], rx_pwr_all=0;
5233        //long                          rx_avg_pwr = 0;
5234        char                            rx_snrX, rx_evmX;
5235        u8                              evm, pwdb_all;
5236        u32                     RSSI, total_rssi=0;//, total_evm=0;
5237//      long                            signal_strength_index = 0;
5238        u8                              is_cck_rate=0;
5239        u8                              rf_rx_num = 0;
5240
5241        /* 2007/07/04 MH For OFDM RSSI. For high power or not. */
5242        static  u8              check_reg824 = 0;
5243        static  u32             reg824_bit9 = 0;
5244
5245        priv->stats.numqry_phystatus++;
5246
5247        is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
5248
5249        // Record it for next packet processing
5250        memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
5251        pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
5252        pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
5253        pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
5254        pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
5255        pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
5256        /*2007.08.30 requested by SD3 Jerry */
5257        if(check_reg824 == 0)
5258        {
5259                reg824_bit9 = rtl8192_QueryBBReg(priv->ieee80211->dev, rFPGA0_XA_HSSIParameter2, 0x200);
5260                check_reg824 = 1;
5261        }
5262
5263
5264        prxpkt = (u8*)pdrvinfo;
5265
5266        /* Move pointer to the 16th bytes. Phy status start address. */
5267        prxpkt += sizeof(rx_fwinfo_819x_pci);
5268
5269        /* Initial the cck and ofdm buffer pointer */
5270        pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt;
5271        pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt;
5272
5273        pstats->RxMIMOSignalQuality[0] = -1;
5274        pstats->RxMIMOSignalQuality[1] = -1;
5275        precord_stats->RxMIMOSignalQuality[0] = -1;
5276        precord_stats->RxMIMOSignalQuality[1] = -1;
5277
5278        if(is_cck_rate)
5279        {
5280                //
5281                // (1)Hardware does not provide RSSI for CCK
5282                //
5283
5284                //
5285                // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5286                //
5287                u8 report;//, cck_agc_rpt;
5288#ifdef RTL8190P
5289                u8 tmp_pwdb;
5290                char cck_adc_pwdb[4];
5291#endif
5292                priv->stats.numqry_phystatusCCK++;
5293
5294#ifdef RTL8190P //Only 90P 2T4R need to check
5295                if(priv->rf_type == RF_2T4R && DM_RxPathSelTable.Enable && bpacket_match_bssid)
5296                {
5297                        for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5298                        {
5299                                tmp_pwdb = pcck_buf->adc_pwdb_X[i];
5300                                cck_adc_pwdb[i] = (char)tmp_pwdb;
5301                                cck_adc_pwdb[i] /= 2;
5302                                pstats->cck_adc_pwdb[i] = precord_stats->cck_adc_pwdb[i] = cck_adc_pwdb[i];
5303                                //DbgPrint("RF-%d tmp_pwdb = 0x%x, cck_adc_pwdb = %d", i, tmp_pwdb, cck_adc_pwdb[i]);
5304                        }
5305                }
5306#endif
5307
5308                if(!reg824_bit9)
5309                {
5310                        report = pcck_buf->cck_agc_rpt & 0xc0;
5311                        report = report>>6;
5312                        switch(report)
5313                        {
5314                                //Fixed by Jacken from Bryant 2008-03-20
5315                                //Original value is -38 , -26 , -14 , -2
5316                                //Fixed value is -35 , -23 , -11 , 6
5317                                case 0x3:
5318                                        rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
5319                                        break;
5320                                case 0x2:
5321                                        rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
5322                                        break;
5323                                case 0x1:
5324                                        rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
5325                                        break;
5326                                case 0x0:
5327                                        rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e);
5328                                        break;
5329                        }
5330                }
5331                else
5332                {
5333                        report = pcck_buf->cck_agc_rpt & 0x60;
5334                        report = report>>5;
5335                        switch(report)
5336                        {
5337                                case 0x3:
5338                                        rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5339                                        break;
5340                                case 0x2:
5341                                        rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
5342                                        break;
5343                                case 0x1:
5344                                        rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5345                                        break;
5346                                case 0x0:
5347                                        rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5348                                        break;
5349                        }
5350                }
5351
5352                pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5353                pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5354                pstats->RecvSignalPower = rx_pwr_all;
5355
5356                //
5357                // (3) Get Signal Quality (EVM)
5358                //
5359                if(bpacket_match_bssid)
5360                {
5361                        u8      sq;
5362
5363                        if(pstats->RxPWDBAll > 40)
5364                        {
5365                                sq = 100;
5366                        }else
5367                        {
5368                                sq = pcck_buf->sq_rpt;
5369
5370                                if(pcck_buf->sq_rpt > 64)
5371                                        sq = 0;
5372                                else if (pcck_buf->sq_rpt < 20)
5373                                        sq = 100;
5374                                else
5375                                        sq = ((64-sq) * 100) / 44;
5376                        }
5377                        pstats->SignalQuality = precord_stats->SignalQuality = sq;
5378                        pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5379                        pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5380                }
5381        }
5382        else
5383        {
5384                priv->stats.numqry_phystatusHT++;
5385                //
5386                // (1)Get RSSI for HT rate
5387                //
5388                for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++)
5389                {
5390                        // 2008/01/30 MH we will judge RF RX path now.
5391                        if (priv->brfpath_rxenable[i])
5392                                rf_rx_num++;
5393                        //else
5394                                //continue;
5395
5396                        //Fixed by Jacken from Bryant 2008-03-20
5397                        //Original value is 106
5398#ifdef RTL8190P    //Modify by Jacken 2008/03/31
5399                        rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5400#else
5401                        rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
5402#endif
5403
5404                        //Get Rx snr value in DB
5405                        tmp_rxsnr = pofdm_buf->rxsnr_X[i];
5406                        rx_snrX = (char)(tmp_rxsnr);
5407                        rx_snrX /= 2;
5408                        priv->stats.rxSNRdB[i] = (long)rx_snrX;
5409
5410                        /* Translate DBM to percentage. */
5411                        RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5412                        if (priv->brfpath_rxenable[i])
5413                                total_rssi += RSSI;
5414
5415                        /* Record Signal Strength for next packet */
5416                        if(bpacket_match_bssid)
5417                        {
5418                                pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5419                                precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5420                        }
5421                }
5422
5423
5424                //
5425                // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5426                //
5427                //Fixed by Jacken from Bryant 2008-03-20
5428                //Original value is 106
5429                rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5430                pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5431
5432                pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5433                pstats->RxPower = precord_stats->RxPower =      rx_pwr_all;
5434                pstats->RecvSignalPower = rx_pwr_all;
5435                //
5436                // (3)EVM of HT rate
5437                //
5438                if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5439                        pdrvinfo->RxRate<=DESC90_RATEMCS15)
5440                        max_spatial_stream = 2; //both spatial stream make sense
5441                else
5442                        max_spatial_stream = 1; //only spatial stream 1 makes sense
5443
5444                for(i=0; i<max_spatial_stream; i++)
5445                {
5446                        tmp_rxevm = pofdm_buf->rxevm_X[i];
5447                        rx_evmX = (char)(tmp_rxevm);
5448
5449                        // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5450                        // fill most significant bit to "zero" when doing shifting operation which may change a negative
5451                        // value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
5452                        rx_evmX /= 2;   //dbm
5453
5454                        evm = rtl819x_evm_dbtopercentage(rx_evmX);
5455#if 0
5456                        EVM = SignalScaleMapping(EVM);//make it good looking, from 0~100
5457#endif
5458                        if(bpacket_match_bssid)
5459                        {
5460                                if(i==0) // Fill value in RFD, Get the first spatial stream only
5461                                        pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5462                                pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5463                        }
5464                }
5465
5466
5467                /* record rx statistics for debug */
5468                rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5469                prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5470                if(pdrvinfo->BW)        //40M channel
5471                        priv->stats.received_bwtype[1+prxsc->rxsc]++;
5472                else                            //20M channel
5473                        priv->stats.received_bwtype[0]++;
5474        }
5475
5476        //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5477        //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5478        if(is_cck_rate)
5479        {
5480                pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5481
5482        }
5483        else
5484        {
5485                //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX);
5486                // We can judge RX path number now.
5487                if (rf_rx_num != 0)
5488                        pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5489        }
5490}       /* QueryRxPhyStatus8190Pci */
5491
5492static void
5493rtl8192_record_rxdesc_forlateruse(
5494        struct ieee80211_rx_stats * psrc_stats,
5495        struct ieee80211_rx_stats * ptarget_stats
5496)
5497{
5498        ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5499        ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5500        //ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5501}
5502
5503
5504
5505static void TranslateRxSignalStuff819xpci(struct net_device *dev,
5506        struct sk_buff *skb,
5507        struct ieee80211_rx_stats * pstats,
5508        prx_desc_819x_pci pdesc,
5509        prx_fwinfo_819x_pci pdrvinfo)
5510{
5511    // TODO: We must only check packet for current MAC address. Not finish
5512    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5513    bool bpacket_match_bssid, bpacket_toself;
5514    bool bPacketBeacon=false, bToSelfBA=false;
5515    static struct ieee80211_rx_stats  previous_stats;
5516    struct ieee80211_hdr_3addr *hdr;
5517    u16 fc,type;
5518
5519    // Get Signal Quality for only RX data queue (but not command queue)
5520
5521    u8* tmp_buf;
5522    u8  *praddr;
5523
5524    /* Get MAC frame start address. */
5525    tmp_buf = skb->data;
5526
5527    hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5528    fc = le16_to_cpu(hdr->frame_ctl);
5529    type = WLAN_FC_GET_TYPE(fc);
5530    praddr = hdr->addr1;
5531
5532    /* Check if the received packet is acceptabe. */
5533    bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5534            (eqMacAddr(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5535            && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5536    bpacket_toself =  bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5537#if 1//cosa
5538    if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5539    {
5540        bPacketBeacon = true;
5541        //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5542    }
5543    if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5544    {
5545        if((eqMacAddr(praddr,dev->dev_addr)))
5546            bToSelfBA = true;
5547        //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5548    }
5549
5550#endif
5551    if(bpacket_match_bssid)
5552    {
5553        priv->stats.numpacket_matchbssid++;
5554    }
5555    if(bpacket_toself){
5556        priv->stats.numpacket_toself++;
5557    }
5558    //
5559    // Process PHY information for previous packet (RSSI/PWDB/EVM)
5560    //
5561    // Because phy information is contained in the last packet of AMPDU only, so driver
5562    // should process phy information of previous packet
5563    rtl8192_process_phyinfo(priv, tmp_buf,&previous_stats, pstats);
5564    rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &previous_stats, bpacket_match_bssid,
5565            bpacket_toself ,bPacketBeacon, bToSelfBA);
5566    rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5567
5568}
5569
5570
5571static void rtl8192_tx_resume(struct net_device *dev)
5572{
5573        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5574        struct ieee80211_device *ieee = priv->ieee80211;
5575        struct sk_buff *skb;
5576        int queue_index;
5577
5578        for(queue_index = BK_QUEUE; queue_index < TXCMD_QUEUE;queue_index++) {
5579                while((!skb_queue_empty(&ieee->skb_waitQ[queue_index]))&&
5580                                (priv->ieee80211->check_nic_enough_desc(dev,queue_index) > 0)) {
5581                        /* 1. dequeue the packet from the wait queue */
5582                        skb = skb_dequeue(&ieee->skb_waitQ[queue_index]);
5583                        /* 2. tx the packet directly */
5584                        ieee->softmac_data_hard_start_xmit(skb,dev,0/* rate useless now*/);
5585                        #if 0
5586                        if(queue_index!=MGNT_QUEUE) {
5587                                ieee->stats.tx_packets++;
5588                                ieee->stats.tx_bytes += skb->len;
5589                        }
5590                        #endif
5591                }
5592        }
5593}
5594
5595void rtl8192_irq_tx_tasklet(struct r8192_priv *priv)
5596{
5597       rtl8192_tx_resume(priv->ieee80211->dev);
5598}
5599
5600/**
5601* Function:     UpdateReceivedRateHistogramStatistics
5602* Overview:     Recored down the received data rate
5603*
5604* Input:
5605*       PADAPTER        Adapter
5606*       PRT_RFD         pRfd,
5607*
5608* Output:
5609*       PRT_TCB         Adapter
5610*                               (Adapter->RxStats.ReceivedRateHistogram[] is updated)
5611* Return:
5612*               None
5613*/
5614static void UpdateReceivedRateHistogramStatistics8190(
5615        struct net_device *dev,
5616        struct ieee80211_rx_stats* pstats
5617        )
5618{
5619        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5620        u32 rcvType=1;   //0: Total, 1:OK, 2:CRC, 3:ICV
5621        u32 rateIndex;
5622        u32 preamble_guardinterval;  //1: short preamble/GI, 0: long preamble/GI
5623
5624        /* 2007/03/09 MH We will not update rate of packet from rx cmd queue. */
5625        #if 0
5626        if (pRfd->queue_id == CMPK_RX_QUEUE_ID)
5627                return;
5628        #endif
5629        if(pstats->bCRC)
5630                rcvType = 2;
5631        else if(pstats->bICV)
5632                rcvType = 3;
5633
5634        if(pstats->bShortPreamble)
5635                preamble_guardinterval = 1;// short
5636        else
5637                preamble_guardinterval = 0;// long
5638
5639        switch(pstats->rate)
5640        {
5641                //
5642                // CCK rate
5643                //
5644                case MGN_1M:    rateIndex = 0;  break;
5645                case MGN_2M:    rateIndex = 1;  break;
5646                case MGN_5_5M:  rateIndex = 2;  break;
5647                case MGN_11M:   rateIndex = 3;  break;
5648                //
5649                // Legacy OFDM rate
5650                //
5651                case MGN_6M:    rateIndex = 4;  break;
5652                case MGN_9M:    rateIndex = 5;  break;
5653                case MGN_12M:   rateIndex = 6;  break;
5654                case MGN_18M:   rateIndex = 7;  break;
5655                case MGN_24M:   rateIndex = 8;  break;
5656                case MGN_36M:   rateIndex = 9;  break;
5657                case MGN_48M:   rateIndex = 10; break;
5658                case MGN_54M:   rateIndex = 11; break;
5659                //
5660                // 11n High throughput rate
5661                //
5662                case MGN_MCS0:  rateIndex = 12; break;
5663                case MGN_MCS1:  rateIndex = 13; break;
5664                case MGN_MCS2:  rateIndex = 14; break;
5665                case MGN_MCS3:  rateIndex = 15; break;
5666                case MGN_MCS4:  rateIndex = 16; break;
5667                case MGN_MCS5:  rateIndex = 17; break;
5668                case MGN_MCS6:  rateIndex = 18; break;
5669                case MGN_MCS7:  rateIndex = 19; break;
5670                case MGN_MCS8:  rateIndex = 20; break;
5671                case MGN_MCS9:  rateIndex = 21; break;
5672                case MGN_MCS10: rateIndex = 22; break;
5673                case MGN_MCS11: rateIndex = 23; break;
5674                case MGN_MCS12: rateIndex = 24; break;
5675                case MGN_MCS13: rateIndex = 25; break;
5676                case MGN_MCS14: rateIndex = 26; break;
5677                case MGN_MCS15: rateIndex = 27; break;
5678                default:        rateIndex = 28; break;
5679        }
5680        priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5681        priv->stats.received_rate_histogram[0][rateIndex]++; //total
5682        priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5683}
5684
5685static void rtl8192_rx(struct net_device *dev)
5686{
5687    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5688    struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5689    bool unicast_packet = false;
5690    struct ieee80211_rx_stats stats = {
5691        .signal = 0,
5692        .noise = -98,
5693        .rate = 0,
5694        .freq = IEEE80211_24GHZ_BAND,
5695    };
5696    unsigned int count = priv->rxringcount;
5697
5698    stats.nic_type = NIC_8192E;
5699
5700    while (count--) {
5701        rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor
5702        struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt
5703
5704        if (pdesc->OWN){
5705            /* wait data to be filled by hardware */
5706            return;
5707        } else {
5708            stats.bICV = pdesc->ICV;
5709            stats.bCRC = pdesc->CRC32;
5710            stats.bHwError = pdesc->CRC32 | pdesc->ICV;
5711
5712            stats.Length = pdesc->Length;
5713            if(stats.Length < 24)
5714                stats.bHwError |= 1;
5715
5716            if(stats.bHwError) {
5717                stats.bShift = false;
5718
5719                if(pdesc->CRC32) {
5720                    if (pdesc->Length <500)
5721                        priv->stats.rxcrcerrmin++;
5722                    else if (pdesc->Length >1000)
5723                        priv->stats.rxcrcerrmax++;
5724                    else
5725                        priv->stats.rxcrcerrmid++;
5726                }
5727                goto done;
5728            } else {
5729                prx_fwinfo_819x_pci pDrvInfo = NULL;
5730                struct sk_buff *new_skb = dev_alloc_skb(priv->rxbuffersize);
5731
5732                if (unlikely(!new_skb)) {
5733                    goto done;
5734                }
5735
5736                stats.RxDrvInfoSize = pdesc->RxDrvInfoSize;
5737                stats.RxBufShift = ((pdesc->Shift)&0x03);
5738                stats.Decrypted = !pdesc->SWDec;
5739
5740                pci_dma_sync_single_for_cpu(priv->pdev,
5741                     *((dma_addr_t *)skb->cb),
5742                     priv->rxbuffersize,
5743                     PCI_DMA_FROMDEVICE);
5744                skb_put(skb, pdesc->Length);
5745                pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift);
5746                skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift);
5747
5748                stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate);
5749                stats.bShortPreamble = pDrvInfo->SPLCP;
5750
5751                /* it is debug only. It should be disabled in released driver.
5752                 * 2007.1.11 by Emily
5753                 * */
5754                UpdateReceivedRateHistogramStatistics8190(dev, &stats);
5755
5756                stats.bIsAMPDU = (pDrvInfo->PartAggr==1);
5757                stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1);
5758
5759                stats.TimeStampLow = pDrvInfo->TSFL;
5760                stats.TimeStampHigh = read_nic_dword(dev, TSFR+4);
5761
5762                UpdateRxPktTimeStamp8190(dev, &stats);
5763
5764                //
5765                // Get Total offset of MPDU Frame Body
5766                //
5767                if((stats.RxBufShift + stats.RxDrvInfoSize) > 0)
5768                    stats.bShift = 1;
5769
5770                stats.RxIs40MHzPacket = pDrvInfo->BW;
5771
5772                /* ???? */
5773                TranslateRxSignalStuff819xpci(dev,skb, &stats, pdesc, pDrvInfo);
5774
5775                /* Rx A-MPDU */
5776                if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1)
5777                    RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n",
5778                            pDrvInfo->FirstAGGR, pDrvInfo->PartAggr);
5779                   skb_trim(skb, skb->len - 4/*sCrcLng*/);
5780                /* rx packets statistics */
5781                ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5782                unicast_packet = false;
5783
5784                if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5785                    //TODO
5786                }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5787                    //TODO
5788                }else {
5789                    /* unicast packet */
5790                    unicast_packet = true;
5791                }
5792
5793                stats.packetlength = stats.Length-4;
5794                stats.fraglength = stats.packetlength;
5795                stats.fragoffset = 0;
5796                stats.ntotalfrag = 1;
5797
5798                if(!ieee80211_rx(priv->ieee80211, skb, &stats)){
5799                    dev_kfree_skb_any(skb);
5800                } else {
5801                    priv->stats.rxok++;
5802                    if(unicast_packet) {
5803                        priv->stats.rxbytesunicast += skb->len;
5804                    }
5805                }
5806
5807                skb = new_skb;
5808                priv->rx_buf[priv->rx_idx] = skb;
5809                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb->tail, priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5810//                *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE);
5811            }
5812
5813        }
5814done:
5815        pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb));
5816        pdesc->OWN = 1;
5817        pdesc->Length = priv->rxbuffersize;
5818        if (priv->rx_idx == priv->rxringcount-1)
5819            pdesc->EOR = 1;
5820        priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount;
5821    }
5822
5823}
5824
5825void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5826{
5827       rtl8192_rx(priv->ieee80211->dev);
5828        /* unmask RDU */
5829       write_nic_dword(priv->ieee80211->dev, INTA_MASK,read_nic_dword(priv->ieee80211->dev, INTA_MASK) | IMR_RDU);
5830}
5831
5832static const struct net_device_ops rtl8192_netdev_ops = {
5833        .ndo_open =                     rtl8192_open,
5834        .ndo_stop =                     rtl8192_close,
5835/*      .ndo_get_stats =                rtl8192_stats, */
5836        .ndo_tx_timeout =               tx_timeout,
5837        .ndo_do_ioctl =                 rtl8192_ioctl,
5838        .ndo_set_multicast_list =       r8192_set_multicast,
5839        .ndo_set_mac_address =          r8192_set_mac_adr,
5840        .ndo_start_xmit =               ieee80211_xmit,
5841};
5842
5843/****************************************************************************
5844     ---------------------------- PCI_STUFF---------------------------
5845*****************************************************************************/
5846
5847static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
5848                         const struct pci_device_id *id)
5849{
5850        unsigned long ioaddr = 0;
5851        struct net_device *dev = NULL;
5852        struct r8192_priv *priv= NULL;
5853        u8 unit = 0;
5854
5855#ifdef CONFIG_RTL8192_IO_MAP
5856        unsigned long pio_start, pio_len, pio_flags;
5857#else
5858        unsigned long pmem_start, pmem_len, pmem_flags;
5859#endif //end #ifdef RTL_IO_MAP
5860
5861        RT_TRACE(COMP_INIT,"Configuring chip resources");
5862
5863        if( pci_enable_device (pdev) ){
5864                RT_TRACE(COMP_ERR,"Failed to enable PCI device");
5865                return -EIO;
5866        }
5867
5868        pci_set_master(pdev);
5869        //pci_set_wmi(pdev);
5870        pci_set_dma_mask(pdev, 0xffffff00ULL);
5871        pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
5872        dev = alloc_ieee80211(sizeof(struct r8192_priv));
5873        if (!dev)
5874                return -ENOMEM;
5875
5876        pci_set_drvdata(pdev, dev);
5877        SET_NETDEV_DEV(dev, &pdev->dev);
5878        priv = ieee80211_priv(dev);
5879        priv->ieee80211 = netdev_priv(dev);
5880        priv->pdev=pdev;
5881        if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){
5882                priv->ieee80211->bSupportRemoteWakeUp = 1;
5883        } else
5884        {
5885                priv->ieee80211->bSupportRemoteWakeUp = 0;
5886        }
5887
5888#ifdef CONFIG_RTL8192_IO_MAP
5889
5890        pio_start = (unsigned long)pci_resource_start (pdev, 0);
5891        pio_len = (unsigned long)pci_resource_len (pdev, 0);
5892        pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
5893
5894        if (!(pio_flags & IORESOURCE_IO)) {
5895                RT_TRACE(COMP_ERR,"region #0 not a PIO resource, aborting");
5896                goto fail;
5897        }
5898
5899        //DMESG("IO space @ 0x%08lx", pio_start );
5900        if( ! request_region( pio_start, pio_len, RTL819xE_MODULE_NAME ) ){
5901                RT_TRACE(COMP_ERR,"request_region failed!");
5902                goto fail;
5903        }
5904
5905        ioaddr = pio_start;
5906        dev->base_addr = ioaddr; // device I/O address
5907
5908#else
5909
5910        pmem_start = pci_resource_start(pdev, 1);
5911        pmem_len = pci_resource_len(pdev, 1);
5912        pmem_flags = pci_resource_flags (pdev, 1);
5913
5914        if (!(pmem_flags & IORESOURCE_MEM)) {
5915                RT_TRACE(COMP_ERR,"region #1 not a MMIO resource, aborting");
5916                goto fail;
5917        }
5918
5919        //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
5920        if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) {
5921                RT_TRACE(COMP_ERR,"request_mem_region failed!");
5922                goto fail;
5923        }
5924
5925
5926        ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
5927        if( ioaddr == (unsigned long)NULL ){
5928                RT_TRACE(COMP_ERR,"ioremap failed!");
5929               // release_mem_region( pmem_start, pmem_len );
5930                goto fail1;
5931        }
5932
5933        dev->mem_start = ioaddr; // shared mem start
5934        dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
5935
5936#endif //end #ifdef RTL_IO_MAP
5937
5938        /* We disable the RETRY_TIMEOUT register (0x41) to keep
5939         * PCI Tx retries from interfering with C3 CPU state */
5940         pci_write_config_byte(pdev, 0x41, 0x00);
5941
5942
5943        pci_read_config_byte(pdev, 0x05, &unit);
5944        pci_write_config_byte(pdev, 0x05, unit & (~0x04));
5945
5946        dev->irq = pdev->irq;
5947        priv->irq = 0;
5948
5949        dev->netdev_ops = &rtl8192_netdev_ops;
5950#if 0
5951        dev->open = rtl8192_open;
5952        dev->stop = rtl8192_close;
5953        //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
5954        dev->tx_timeout = tx_timeout;
5955        //dev->wireless_handlers = &r8192_wx_handlers_def;
5956        dev->do_ioctl = rtl8192_ioctl;
5957        dev->set_multicast_list = r8192_set_multicast;
5958        dev->set_mac_address = r8192_set_mac_adr;
5959#endif
5960
5961         //DMESG("Oops: i'm coming\n");
5962#if WIRELESS_EXT >= 12
5963#if WIRELESS_EXT < 17
5964        dev->get_wireless_stats = r8192_get_wireless_stats;
5965#endif
5966        dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5967#endif
5968       //dev->get_wireless_stats = r8192_get_wireless_stats;
5969        dev->type=ARPHRD_ETHER;
5970
5971        dev->watchdog_timeo = HZ*3;     //modified by john, 0805
5972
5973        if (dev_alloc_name(dev, ifname) < 0){
5974                RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5975                ifname = "wlan%d";
5976                dev_alloc_name(dev, ifname);
5977        }
5978
5979        RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5980        if(rtl8192_init(dev)!=0){
5981                RT_TRACE(COMP_ERR, "Initialization failed");
5982                goto fail;
5983        }
5984
5985        netif_carrier_off(dev);
5986        netif_stop_queue(dev);
5987
5988        register_netdev(dev);
5989        RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5990        rtl8192_proc_init_one(dev);
5991
5992
5993        RT_TRACE(COMP_INIT, "Driver probe completed\n");
5994        return 0;
5995
5996fail1:
5997
5998#ifdef CONFIG_RTL8180_IO_MAP
5999
6000        if( dev->base_addr != 0 ){
6001
6002                release_region(dev->base_addr,
6003               pci_resource_len(pdev, 0) );
6004        }
6005#else
6006        if( dev->mem_start != (unsigned long)NULL ){
6007                iounmap( (void *)dev->mem_start );
6008                release_mem_region( pci_resource_start(pdev, 1),
6009                                    pci_resource_len(pdev, 1) );
6010        }
6011#endif //end #ifdef RTL_IO_MAP
6012
6013fail:
6014        if(dev){
6015
6016                if (priv->irq) {
6017                        free_irq(dev->irq, dev);
6018                        dev->irq=0;
6019                }
6020                free_ieee80211(dev);
6021        }
6022
6023        pci_disable_device(pdev);
6024
6025        DMESG("wlan driver load failed\n");
6026        pci_set_drvdata(pdev, NULL);
6027        return -ENODEV;
6028
6029}
6030
6031/* detach all the work and timer structure declared or inititialized
6032 * in r8192_init function.
6033 * */
6034void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
6035{
6036        /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code
6037         * is  or is newer than 2.6.20 and work structure is defined to be struct work_struct.
6038         * Otherwise call cancel_delayed_work is enough.
6039         * FIXME (2.6.20 shoud 2.6.22, work_struct shoud not cancel)
6040         * */
6041        cancel_delayed_work(&priv->watch_dog_wq);
6042        cancel_delayed_work(&priv->update_beacon_wq);
6043        cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
6044        cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
6045#ifdef RTL8192E
6046        cancel_delayed_work(&priv->gpio_change_rf_wq);
6047#endif
6048        cancel_work_sync(&priv->reset_wq);
6049        cancel_work_sync(&priv->qos_activate);
6050        //cancel_work_sync(&priv->SetBWModeWorkItem);
6051        //cancel_work_sync(&priv->SwChnlWorkItem);
6052
6053}
6054
6055
6056static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev)
6057{
6058        struct net_device *dev = pci_get_drvdata(pdev);
6059        struct r8192_priv *priv ;
6060
6061        if(dev){
6062
6063                unregister_netdev(dev);
6064
6065                priv=ieee80211_priv(dev);
6066
6067                rtl8192_proc_remove_one(dev);
6068
6069                rtl8192_down(dev);
6070                if (priv->pFirmware)
6071                {
6072                        vfree(priv->pFirmware);
6073                        priv->pFirmware = NULL;
6074                }
6075        //      priv->rf_close(dev);
6076        //      rtl8192_usb_deleteendpoints(dev);
6077                destroy_workqueue(priv->priv_wq);
6078                /* redundant with rtl8192_down */
6079               // rtl8192_irq_disable(dev);
6080               // rtl8192_reset(dev);
6081               // mdelay(10);
6082                {
6083                    u32 i;
6084                    /* free tx/rx rings */
6085                    rtl8192_free_rx_ring(dev);
6086                    for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) {
6087                        rtl8192_free_tx_ring(dev, i);
6088                    }
6089                }
6090                if(priv->irq){
6091
6092                        printk("Freeing irq %d\n",dev->irq);
6093                        free_irq(dev->irq, dev);
6094                        priv->irq=0;
6095
6096                }
6097
6098
6099
6100        //      free_beacon_desc_ring(dev,priv->txbeaconcount);
6101
6102#ifdef CONFIG_RTL8180_IO_MAP
6103
6104                if( dev->base_addr != 0 ){
6105
6106                        release_region(dev->base_addr,
6107                                       pci_resource_len(pdev, 0) );
6108                }
6109#else
6110                if( dev->mem_start != (unsigned long)NULL ){
6111                        iounmap( (void *)dev->mem_start );
6112                        release_mem_region( pci_resource_start(pdev, 1),
6113                                            pci_resource_len(pdev, 1) );
6114                }
6115#endif /*end #ifdef RTL_IO_MAP*/
6116                free_ieee80211(dev);
6117
6118        }
6119
6120        pci_disable_device(pdev);
6121        RT_TRACE(COMP_DOWN, "wlan driver removed\n");
6122}
6123
6124extern int ieee80211_init(void);
6125extern void ieee80211_exit(void);
6126
6127static int __init rtl8192_pci_module_init(void)
6128{
6129        int retval;
6130
6131        retval = ieee80211_init();
6132        if (retval)
6133                return retval;
6134
6135        printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
6136        printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
6137        RT_TRACE(COMP_INIT, "Initializing module");
6138        RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
6139        rtl8192_proc_module_init();
6140      if(0!=pci_register_driver(&rtl8192_pci_driver))
6141        {
6142                DMESG("No device found");
6143                /*pci_unregister_driver (&rtl8192_pci_driver);*/
6144                return -ENODEV;
6145        }
6146        return 0;
6147}
6148
6149
6150static void __exit rtl8192_pci_module_exit(void)
6151{
6152        pci_unregister_driver(&rtl8192_pci_driver);
6153
6154        RT_TRACE(COMP_DOWN, "Exiting");
6155        rtl8192_proc_module_remove();
6156        ieee80211_exit();
6157}
6158
6159//warning message WB
6160irqreturn_t rtl8192_interrupt(int irq, void *netdev)
6161{
6162    struct net_device *dev = (struct net_device *) netdev;
6163    struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6164    unsigned long flags;
6165    u32 inta;
6166    /* We should return IRQ_NONE, but for now let me keep this */
6167    if(priv->irq_enabled == 0){
6168        return IRQ_HANDLED;
6169    }
6170
6171    spin_lock_irqsave(&priv->irq_th_lock,flags);
6172
6173    //ISR: 4bytes
6174
6175    inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
6176    write_nic_dword(dev,ISR,inta); // reset int situation
6177
6178    priv->stats.shints++;
6179    //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
6180    if(!inta){
6181        spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6182        return IRQ_HANDLED;
6183        /*
6184           most probably we can safely return IRQ_NONE,
6185           but for now is better to avoid problems
6186           */
6187    }
6188
6189    if(inta == 0xffff){
6190        /* HW disappared */
6191        spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6192        return IRQ_HANDLED;
6193    }
6194
6195    priv->stats.ints++;
6196#ifdef DEBUG_IRQ
6197    DMESG("NIC irq %x",inta);
6198#endif
6199    //priv->irqpending = inta;
6200
6201
6202    if(!netif_running(dev)) {
6203        spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6204        return IRQ_HANDLED;
6205    }
6206
6207    if(inta & IMR_TIMEOUT0){
6208        //              write_nic_dword(dev, TimerInt, 0);
6209        //DMESG("=================>waking up");
6210        //              rtl8180_hw_wakeup(dev);
6211    }
6212
6213    if(inta & IMR_TBDOK){
6214        RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6215        rtl8192_tx_isr(dev, BEACON_QUEUE);
6216        priv->stats.txbeaconokint++;
6217    }
6218
6219    if(inta & IMR_TBDER){
6220        RT_TRACE(COMP_INTR, "beacon ok interrupt!\n");
6221        rtl8192_tx_isr(dev, BEACON_QUEUE);
6222        priv->stats.txbeaconerr++;
6223    }
6224
6225    if(inta  & IMR_MGNTDOK ) {
6226        RT_TRACE(COMP_INTR, "Manage ok interrupt!\n");
6227        priv->stats.txmanageokint++;
6228        rtl8192_tx_isr(dev,MGNT_QUEUE);
6229
6230    }
6231
6232    if(inta & IMR_COMDOK)
6233    {
6234        priv->stats.txcmdpktokint++;
6235        rtl8192_tx_isr(dev,TXCMD_QUEUE);
6236    }
6237
6238    if(inta & IMR_ROK){
6239#ifdef DEBUG_RX
6240        DMESG("Frame arrived !");
6241#endif
6242        priv->stats.rxint++;
6243        tasklet_schedule(&priv->irq_rx_tasklet);
6244    }
6245
6246    if(inta & IMR_BcnInt) {
6247        RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n");
6248        tasklet_schedule(&priv->irq_prepare_beacon_tasklet);
6249    }
6250
6251    if(inta & IMR_RDU){
6252        RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n");
6253        priv->stats.rxrdu++;
6254        /* reset int situation */
6255        write_nic_dword(dev,INTA_MASK,read_nic_dword(dev, INTA_MASK) & ~IMR_RDU);
6256        tasklet_schedule(&priv->irq_rx_tasklet);
6257    }
6258
6259    if(inta & IMR_RXFOVW){
6260        RT_TRACE(COMP_INTR, "rx overflow !\n");
6261        priv->stats.rxoverflow++;
6262        tasklet_schedule(&priv->irq_rx_tasklet);
6263    }
6264
6265    if(inta & IMR_TXFOVW) priv->stats.txoverflow++;
6266
6267    if(inta & IMR_BKDOK){
6268        RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n");
6269        priv->stats.txbkokint++;
6270        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6271        rtl8192_tx_isr(dev,BK_QUEUE);
6272        rtl8192_try_wake_queue(dev, BK_QUEUE);
6273    }
6274
6275    if(inta & IMR_BEDOK){
6276        RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n");
6277        priv->stats.txbeokint++;
6278        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6279        rtl8192_tx_isr(dev,BE_QUEUE);
6280        rtl8192_try_wake_queue(dev, BE_QUEUE);
6281    }
6282
6283    if(inta & IMR_VIDOK){
6284        RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n");
6285        priv->stats.txviokint++;
6286        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6287        rtl8192_tx_isr(dev,VI_QUEUE);
6288        rtl8192_try_wake_queue(dev, VI_QUEUE);
6289    }
6290
6291    if(inta & IMR_VODOK){
6292        priv->stats.txvookint++;
6293        priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++;
6294        rtl8192_tx_isr(dev,VO_QUEUE);
6295        rtl8192_try_wake_queue(dev, VO_QUEUE);
6296    }
6297
6298    force_pci_posting(dev);
6299    spin_unlock_irqrestore(&priv->irq_th_lock,flags);
6300
6301    return IRQ_HANDLED;
6302}
6303
6304void rtl8192_try_wake_queue(struct net_device *dev, int pri)
6305{
6306#if 0
6307        unsigned long flags;
6308        short enough_desc;
6309        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6310
6311        spin_lock_irqsave(&priv->tx_lock,flags);
6312        enough_desc = check_nic_enough_desc(dev,pri);
6313        spin_unlock_irqrestore(&priv->tx_lock,flags);
6314
6315        if(enough_desc)
6316                ieee80211_wake_queue(priv->ieee80211);
6317#endif
6318}
6319
6320
6321void EnableHWSecurityConfig8192(struct net_device *dev)
6322{
6323        u8 SECR_value = 0x0;
6324        // struct ieee80211_device* ieee1 = container_of(&dev, struct ieee80211_device, dev);
6325         //printk("==>ieee1:%p, dev:%p\n", ieee1, dev);
6326        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6327         struct ieee80211_device* ieee = priv->ieee80211;
6328         //printk("==>ieee:%p, dev:%p\n", ieee, dev);
6329        SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
6330#if 1
6331        if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
6332        {
6333                SECR_value |= SCR_RxUseDK;
6334                SECR_value |= SCR_TxUseDK;
6335        }
6336        else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
6337        {
6338                SECR_value |= SCR_RxUseDK;
6339                SECR_value |= SCR_TxUseDK;
6340        }
6341
6342#endif
6343
6344        //add HWSec active enable here.
6345//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4
6346        ieee->hwsec_active = 1;
6347
6348        if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off
6349        {
6350                ieee->hwsec_active = 0;
6351                SECR_value &= ~SCR_RxDecEnable;
6352        }
6353
6354        RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
6355                        ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
6356        {
6357                write_nic_byte(dev, SECR,  SECR_value);//SECR_value |  SCR_UseDK );
6358        }
6359
6360}
6361#define TOTAL_CAM_ENTRY 32
6362//#define CAM_CONTENT_COUNT 8
6363void setKey(    struct net_device *dev,
6364                u8 EntryNo,
6365                u8 KeyIndex,
6366                u16 KeyType,
6367                u8 *MacAddr,
6368                u8 DefaultKey,
6369                u32 *KeyContent )
6370{
6371        u32 TargetCommand = 0;
6372        u32 TargetContent = 0;
6373        u16 usConfig = 0;
6374        u8 i;
6375#ifdef ENABLE_IPS
6376        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
6377        RT_RF_POWER_STATE       rtState;
6378        rtState = priv->ieee80211->eRFPowerState;
6379        if(priv->ieee80211->PowerSaveControl.bInactivePs){
6380                if(rtState == eRfOff){
6381                        if(priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
6382                        {
6383                                RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__);
6384                                up(&priv->wx_sem);
6385                                return ;
6386                        }
6387                        else{
6388                                IPSLeave(dev);
6389                        }
6390                }
6391        }
6392        priv->ieee80211->is_set_key = true;
6393#endif
6394        if (EntryNo >= TOTAL_CAM_ENTRY)
6395                RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6396
6397        RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr"MAC_FMT"\n", dev,EntryNo, KeyIndex, KeyType, MAC_ARG(MacAddr));
6398
6399        if (DefaultKey)
6400                usConfig |= BIT15 | (KeyType<<2);
6401        else
6402                usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6403//      usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6404
6405
6406        for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6407                TargetCommand  = i+CAM_CONTENT_COUNT*EntryNo;
6408                TargetCommand |= BIT31|BIT16;
6409
6410                if(i==0){//MAC|Config
6411                        TargetContent = (u32)(*(MacAddr+0)) << 16|
6412                                        (u32)(*(MacAddr+1)) << 24|
6413                                        (u32)usConfig;
6414
6415                        write_nic_dword(dev, WCAMI, TargetContent);
6416                        write_nic_dword(dev, RWCAM, TargetCommand);
6417        //              printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6418                }
6419                else if(i==1){//MAC
6420                        TargetContent = (u32)(*(MacAddr+2))      |
6421                                        (u32)(*(MacAddr+3)) <<  8|
6422                                        (u32)(*(MacAddr+4)) << 16|
6423                                        (u32)(*(MacAddr+5)) << 24;
6424                        write_nic_dword(dev, WCAMI, TargetContent);
6425                        write_nic_dword(dev, RWCAM, TargetCommand);
6426                }
6427                else {  //Key Material
6428                        if(KeyContent != NULL)
6429                        {
6430                        write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6431                        write_nic_dword(dev, RWCAM, TargetCommand);
6432                }
6433        }
6434        }
6435        RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig);
6436}
6437// This function seems not ready! WB
6438void CamPrintDbgReg(struct net_device* dev)
6439{
6440        unsigned long rvalue;
6441        unsigned char ucValue;
6442        write_nic_dword(dev, DCAM, 0x80000000);
6443        msleep(40);
6444        rvalue = read_nic_dword(dev, DCAM);     //delay_ms(40);
6445        RT_TRACE(COMP_SEC, " TX CAM=%8lX ",rvalue);
6446        if((rvalue & 0x40000000) != 0x4000000)
6447                RT_TRACE(COMP_SEC, "-->TX Key Not Found      ");
6448        msleep(20);
6449        write_nic_dword(dev, DCAM, 0x00000000); //delay_ms(40);
6450        rvalue = read_nic_dword(dev, DCAM);     //delay_ms(40);
6451        RT_TRACE(COMP_SEC, "RX CAM=%8lX ",rvalue);
6452        if((rvalue & 0x40000000) != 0x4000000)
6453                RT_TRACE(COMP_SEC, "-->CAM Key Not Found   ");
6454        ucValue = read_nic_byte(dev, SECR);
6455        RT_TRACE(COMP_SEC, "WPA_Config=%x \n",ucValue);
6456}
6457
6458
6459/***************************************************************************
6460     ------------------- module init / exit stubs ----------------
6461****************************************************************************/
6462module_init(rtl8192_pci_module_init);
6463module_exit(rtl8192_pci_module_exit);
6464