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