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