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