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 possibility 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 subtract 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        kfree(priv->pp_rxskb);
2246        kfree(priv->rx_urb);
2247
2248        priv->pp_rxskb = NULL;
2249        priv->rx_urb = NULL;
2250
2251        DMESGE("Endpoint Alloc Failure");
2252        return -ENOMEM;
2253
2254
2255_middle:
2256
2257        printk("End of initendpoints\n");
2258        return 0;
2259
2260}
2261#ifdef THOMAS_BEACON
2262void rtl8192_usb_deleteendpoints(struct net_device *dev)
2263{
2264        int i;
2265        struct r8192_priv *priv = ieee80211_priv(dev);
2266
2267        if(priv->rx_urb){
2268                for(i=0;i<(MAX_RX_URB+1);i++){
2269                        usb_kill_urb(priv->rx_urb[i]);
2270                        usb_free_urb(priv->rx_urb[i]);
2271                }
2272                kfree(priv->rx_urb);
2273                priv->rx_urb = NULL;
2274        }
2275        kfree(priv->oldaddr);
2276        priv->oldaddr = NULL;
2277        if (priv->pp_rxskb) {
2278                kfree(priv->pp_rxskb);
2279                priv->pp_rxskb = 0;
2280        }
2281}
2282#else
2283void rtl8192_usb_deleteendpoints(struct net_device *dev)
2284{
2285        int i;
2286        struct r8192_priv *priv = ieee80211_priv(dev);
2287
2288#ifndef JACKSON_NEW_RX
2289
2290        if(priv->rx_urb){
2291                for(i=0;i<(MAX_RX_URB+1);i++){
2292                        usb_kill_urb(priv->rx_urb[i]);
2293                        kfree(priv->rx_urb[i]->transfer_buffer);
2294                        usb_free_urb(priv->rx_urb[i]);
2295                }
2296                kfree(priv->rx_urb);
2297                priv->rx_urb = NULL;
2298
2299        }
2300#else
2301        kfree(priv->rx_urb);
2302        priv->rx_urb = NULL;
2303        kfree(priv->oldaddr);
2304        priv->oldaddr = NULL;
2305        if (priv->pp_rxskb) {
2306                kfree(priv->pp_rxskb);
2307                priv->pp_rxskb = 0;
2308
2309        }
2310
2311#endif
2312}
2313#endif
2314
2315extern void rtl8192_update_ratr_table(struct net_device* dev);
2316void rtl8192_link_change(struct net_device *dev)
2317{
2318//      int i;
2319
2320        struct r8192_priv *priv = ieee80211_priv(dev);
2321        struct ieee80211_device* ieee = priv->ieee80211;
2322        //write_nic_word(dev, BCN_INTR_ITV, net->beacon_interval);
2323        if (ieee->state == IEEE80211_LINKED)
2324        {
2325                rtl8192_net_update(dev);
2326                rtl8192_update_ratr_table(dev);
2327                //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
2328                if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type))
2329                EnableHWSecurityConfig8192(dev);
2330        }
2331        /*update timing params*/
2332//      RT_TRACE(COMP_CH, "========>%s(), chan:%d\n", __FUNCTION__, priv->chan);
2333//      rtl8192_set_chan(dev, priv->chan);
2334         if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
2335        {
2336                u32 reg = 0;
2337                reg = read_nic_dword(dev, RCR);
2338                if (priv->ieee80211->state == IEEE80211_LINKED)
2339                        priv->ReceiveConfig = reg |= RCR_CBSSID;
2340                else
2341                        priv->ReceiveConfig = reg &= ~RCR_CBSSID;
2342                write_nic_dword(dev, RCR, reg);
2343        }
2344
2345//      rtl8192_set_rxconf(dev);
2346}
2347
2348static struct ieee80211_qos_parameters def_qos_parameters = {
2349        {3,3,3,3},/* cw_min */
2350        {7,7,7,7},/* cw_max */
2351        {2,2,2,2},/* aifs */
2352        {0,0,0,0},/* flags */
2353        {0,0,0,0} /* tx_op_limit */
2354};
2355
2356
2357void rtl8192_update_beacon(struct work_struct * work)
2358{
2359        struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work);
2360        struct net_device *dev = priv->ieee80211->dev;
2361        struct ieee80211_device* ieee = priv->ieee80211;
2362        struct ieee80211_network* net = &ieee->current_network;
2363
2364        if (ieee->pHTInfo->bCurrentHTSupport)
2365                HTUpdateSelfAndPeerSetting(ieee, net);
2366        ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime;
2367        rtl8192_update_cap(dev, net->capability);
2368}
2369/*
2370* background support to run QoS activate functionality
2371*/
2372int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO};
2373void rtl8192_qos_activate(struct work_struct * work)
2374{
2375        struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate);
2376        struct net_device *dev = priv->ieee80211->dev;
2377        struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2378        u8 mode = priv->ieee80211->current_network.mode;
2379        //u32 size = sizeof(struct ieee80211_qos_parameters);
2380        u8  u1bAIFS;
2381        u32 u4bAcParam;
2382        int i;
2383
2384        if (priv == NULL)
2385                return;
2386
2387       mutex_lock(&priv->mutex);
2388        if(priv->ieee80211->state != IEEE80211_LINKED)
2389                goto success;
2390        RT_TRACE(COMP_QOS,"qos active process with associate response received\n");
2391        /* It better set slot time at first */
2392        /* For we just support b/g mode at present, let the slot time at 9/20 selection */
2393        /* update the ac parameter to related registers */
2394        for(i = 0; i <  QOS_QUEUE_NUM; i++) {
2395                //Mode G/A: slotTimeTimer = 9; Mode B: 20
2396                u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2397                u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2398                                (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)|
2399                                (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)|
2400                                ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2401
2402                write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2403                //write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332);
2404        }
2405
2406success:
2407       mutex_unlock(&priv->mutex);
2408}
2409
2410static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv,
2411                int active_network,
2412                struct ieee80211_network *network)
2413{
2414        int ret = 0;
2415        u32 size = sizeof(struct ieee80211_qos_parameters);
2416
2417        if(priv->ieee80211->state !=IEEE80211_LINKED)
2418                return ret;
2419
2420        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2421                return ret;
2422
2423        if (network->flags & NETWORK_HAS_QOS_MASK) {
2424                if (active_network &&
2425                                (network->flags & NETWORK_HAS_QOS_PARAMETERS))
2426                        network->qos_data.active = network->qos_data.supported;
2427
2428                if ((network->qos_data.active == 1) && (active_network == 1) &&
2429                                (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&
2430                                (network->qos_data.old_param_count !=
2431                                 network->qos_data.param_count)) {
2432                        network->qos_data.old_param_count =
2433                                network->qos_data.param_count;
2434                        queue_work(priv->priv_wq, &priv->qos_activate);
2435                        RT_TRACE (COMP_QOS, "QoS parameters change call "
2436                                        "qos_activate\n");
2437                }
2438        } else {
2439                memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2440                       &def_qos_parameters, size);
2441
2442                if ((network->qos_data.active == 1) && (active_network == 1)) {
2443                        queue_work(priv->priv_wq, &priv->qos_activate);
2444                        RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate \n");
2445                }
2446                network->qos_data.active = 0;
2447                network->qos_data.supported = 0;
2448        }
2449
2450        return 0;
2451}
2452
2453/* handle manage frame frame beacon and probe response */
2454static int rtl8192_handle_beacon(struct net_device * dev,
2455                              struct ieee80211_beacon * beacon,
2456                              struct ieee80211_network * network)
2457{
2458        struct r8192_priv *priv = ieee80211_priv(dev);
2459
2460        rtl8192_qos_handle_probe_response(priv,1,network);
2461        queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0);
2462        return 0;
2463
2464}
2465
2466/*
2467* handling the beaconing responses. if we get different QoS setting
2468* off the network from the associated setting, adjust the QoS
2469* setting
2470*/
2471static int rtl8192_qos_association_resp(struct r8192_priv *priv,
2472                                    struct ieee80211_network *network)
2473{
2474        int ret = 0;
2475        unsigned long flags;
2476        u32 size = sizeof(struct ieee80211_qos_parameters);
2477        int set_qos_param = 0;
2478
2479        if ((priv == NULL) || (network == NULL))
2480                return ret;
2481
2482        if(priv->ieee80211->state !=IEEE80211_LINKED)
2483                return ret;
2484
2485        if ((priv->ieee80211->iw_mode != IW_MODE_INFRA))
2486                return ret;
2487
2488        spin_lock_irqsave(&priv->ieee80211->lock, flags);
2489        if(network->flags & NETWORK_HAS_QOS_PARAMETERS) {
2490                memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2491                         &network->qos_data.parameters,\
2492                        sizeof(struct ieee80211_qos_parameters));
2493                priv->ieee80211->current_network.qos_data.active = 1;
2494                 {
2495                        set_qos_param = 1;
2496                        /* update qos parameter for current network */
2497                        priv->ieee80211->current_network.qos_data.old_param_count = \
2498                                 priv->ieee80211->current_network.qos_data.param_count;
2499                        priv->ieee80211->current_network.qos_data.param_count = \
2500                                 network->qos_data.param_count;
2501                }
2502        } else {
2503                memcpy(&priv->ieee80211->current_network.qos_data.parameters,\
2504                       &def_qos_parameters, size);
2505                priv->ieee80211->current_network.qos_data.active = 0;
2506                priv->ieee80211->current_network.qos_data.supported = 0;
2507                set_qos_param = 1;
2508        }
2509
2510        spin_unlock_irqrestore(&priv->ieee80211->lock, flags);
2511
2512        RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n",__FUNCTION__,network->flags ,priv->ieee80211->current_network.qos_data.active);
2513        if (set_qos_param == 1)
2514                queue_work(priv->priv_wq, &priv->qos_activate);
2515
2516
2517        return ret;
2518}
2519
2520
2521static int rtl8192_handle_assoc_response(struct net_device *dev,
2522                                     struct ieee80211_assoc_response_frame *resp,
2523                                     struct ieee80211_network *network)
2524{
2525        struct r8192_priv *priv = ieee80211_priv(dev);
2526        rtl8192_qos_association_resp(priv, network);
2527        return 0;
2528}
2529
2530
2531void rtl8192_update_ratr_table(struct net_device* dev)
2532        //      POCTET_STRING   posLegacyRate,
2533        //      u8*                     pMcsRate)
2534        //      PRT_WLAN_STA    pEntry)
2535{
2536        struct r8192_priv* priv = ieee80211_priv(dev);
2537        struct ieee80211_device* ieee = priv->ieee80211;
2538        u8* pMcsRate = ieee->dot11HTOperationalRateSet;
2539        //struct ieee80211_network *net = &ieee->current_network;
2540        u32 ratr_value = 0;
2541        u8 rate_index = 0;
2542        rtl8192_config_rate(dev, (u16*)(&ratr_value));
2543        ratr_value |= (*(u16*)(pMcsRate)) << 12;
2544//      switch (net->mode)
2545        switch (ieee->mode)
2546        {
2547                case IEEE_A:
2548                        ratr_value &= 0x00000FF0;
2549                        break;
2550                case IEEE_B:
2551                        ratr_value &= 0x0000000F;
2552                        break;
2553                case IEEE_G:
2554                        ratr_value &= 0x00000FF7;
2555                        break;
2556                case IEEE_N_24G:
2557                case IEEE_N_5G:
2558                        if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC
2559                                ratr_value &= 0x0007F007;
2560                        else{
2561                                if (priv->rf_type == RF_1T2R)
2562                                        ratr_value &= 0x000FF007;
2563                                else
2564                                        ratr_value &= 0x0F81F007;
2565                        }
2566                        break;
2567                default:
2568                        break;
2569        }
2570        ratr_value &= 0x0FFFFFFF;
2571        if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){
2572                ratr_value |= 0x80000000;
2573        }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){
2574                ratr_value |= 0x80000000;
2575        }
2576        write_nic_dword(dev, RATR0+rate_index*4, ratr_value);
2577        write_nic_byte(dev, UFWP, 1);
2578}
2579
2580static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
2581static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2582bool GetNmodeSupportBySecCfg8192(struct net_device*dev)
2583{
2584        struct r8192_priv* priv = ieee80211_priv(dev);
2585        struct ieee80211_device* ieee = priv->ieee80211;
2586        struct ieee80211_network * network = &ieee->current_network;
2587        int wpa_ie_len= ieee->wpa_ie_len;
2588        struct ieee80211_crypt_data* crypt;
2589        int encrypt;
2590
2591        crypt = ieee->crypt[ieee->tx_keyidx];
2592        //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
2593        encrypt = (network->capability & WLAN_CAPABILITY_PRIVACY) || (ieee->host_encrypt && crypt && crypt->ops && (0 == strcmp(crypt->ops->name,"WEP")));
2594
2595        /* simply judge  */
2596        if(encrypt && (wpa_ie_len == 0)) {
2597                /* wep encryption, no N mode setting */
2598                return false;
2599//      } else if((wpa_ie_len != 0)&&(memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) {
2600        } else if((wpa_ie_len != 0)) {
2601                /* parse pairwise key type */
2602                //if((pairwisekey = WEP40)||(pairwisekey = WEP104)||(pairwisekey = TKIP))
2603                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))))
2604                        return true;
2605                else
2606                        return false;
2607        } else {
2608                return true;
2609        }
2610
2611        return true;
2612}
2613
2614bool GetHalfNmodeSupportByAPs819xUsb(struct net_device* dev)
2615{
2616        bool                    Reval;
2617        struct r8192_priv* priv = ieee80211_priv(dev);
2618        struct ieee80211_device* ieee = priv->ieee80211;
2619
2620        if(ieee->bHalfWirelessN24GMode == true)
2621                Reval = true;
2622        else
2623                Reval =  false;
2624
2625        return Reval;
2626}
2627
2628void rtl8192_refresh_supportrate(struct r8192_priv* priv)
2629{
2630        struct ieee80211_device* ieee = priv->ieee80211;
2631        //we donot consider set support rate for ABG mode, only HT MCS rate is set here.
2632        if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G)
2633        {
2634                memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16);
2635                //RT_DEBUG_DATA(COMP_INIT, ieee->RegHTSuppRateSet, 16);
2636                //RT_DEBUG_DATA(COMP_INIT, ieee->Regdot11HTOperationalRateSet, 16);
2637        }
2638        else
2639                memset(ieee->Regdot11HTOperationalRateSet, 0, 16);
2640        return;
2641}
2642
2643u8 rtl8192_getSupportedWireleeMode(struct net_device*dev)
2644{
2645        struct r8192_priv *priv = ieee80211_priv(dev);
2646        u8 ret = 0;
2647        switch(priv->rf_chip)
2648        {
2649                case RF_8225:
2650                case RF_8256:
2651                case RF_PSEUDO_11N:
2652                        ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B);
2653                        break;
2654                case RF_8258:
2655                        ret = (WIRELESS_MODE_A|WIRELESS_MODE_N_5G);
2656                        break;
2657                default:
2658                        ret = WIRELESS_MODE_B;
2659                        break;
2660        }
2661        return ret;
2662}
2663void rtl8192_SetWirelessMode(struct net_device* dev, u8 wireless_mode)
2664{
2665        struct r8192_priv *priv = ieee80211_priv(dev);
2666        u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev);
2667
2668        if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0))
2669        {
2670                if(bSupportMode & WIRELESS_MODE_N_24G)
2671                {
2672                        wireless_mode = WIRELESS_MODE_N_24G;
2673                }
2674                else if(bSupportMode & WIRELESS_MODE_N_5G)
2675                {
2676                        wireless_mode = WIRELESS_MODE_N_5G;
2677                }
2678                else if((bSupportMode & WIRELESS_MODE_A))
2679                {
2680                        wireless_mode = WIRELESS_MODE_A;
2681                }
2682                else if((bSupportMode & WIRELESS_MODE_G))
2683                {
2684                        wireless_mode = WIRELESS_MODE_G;
2685                }
2686                else if((bSupportMode & WIRELESS_MODE_B))
2687                {
2688                        wireless_mode = WIRELESS_MODE_B;
2689                }
2690                else{
2691                        RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode);
2692                        wireless_mode = WIRELESS_MODE_B;
2693                }
2694        }
2695#ifdef TO_DO_LIST //// TODO: this function doesn't work well at this time, we should wait for FPGA
2696        ActUpdateChannelAccessSetting( pAdapter, pHalData->CurrentWirelessMode, &pAdapter->MgntInfo.Info8185.ChannelAccessSetting );
2697#endif
2698        priv->ieee80211->mode = wireless_mode;
2699
2700        if ((wireless_mode == WIRELESS_MODE_N_24G) ||  (wireless_mode == WIRELESS_MODE_N_5G))
2701                priv->ieee80211->pHTInfo->bEnableHT = 1;
2702        else
2703                priv->ieee80211->pHTInfo->bEnableHT = 0;
2704        RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode);
2705        rtl8192_refresh_supportrate(priv);
2706
2707}
2708//init priv variables here. only non_zero value should be initialized here.
2709static void rtl8192_init_priv_variable(struct net_device* dev)
2710{
2711        struct r8192_priv *priv = ieee80211_priv(dev);
2712        u8 i;
2713        priv->card_8192 = NIC_8192U;
2714        priv->chan = 1; //set to channel 1
2715        priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO
2716        priv->ieee80211->iw_mode = IW_MODE_INFRA;
2717        priv->ieee80211->ieee_up=0;
2718        priv->retry_rts = DEFAULT_RETRY_RTS;
2719        priv->retry_data = DEFAULT_RETRY_DATA;
2720        priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD;
2721        priv->ieee80211->rate = 110; //11 mbps
2722        priv->ieee80211->short_slot = 1;
2723        priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
2724        priv->CckPwEnl = 6;
2725        //for silent reset
2726        priv->IrpPendingCount = 1;
2727        priv->ResetProgress = RESET_TYPE_NORESET;
2728        priv->bForcedSilentReset = 0;
2729        priv->bDisableNormalResetCheck = false;
2730        priv->force_reset = false;
2731
2732        priv->ieee80211->FwRWRF = 0;    //we don't use FW read/write RF until stable firmware is available.
2733        priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
2734        priv->ieee80211->iw_mode = IW_MODE_INFRA;
2735        priv->ieee80211->softmac_features  = IEEE_SOFTMAC_SCAN |
2736                IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
2737                IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE |
2738                IEEE_SOFTMAC_BEACONS;//added by amy 080604 //|  //IEEE_SOFTMAC_SINGLE_QUEUE;
2739
2740        priv->ieee80211->active_scan = 1;
2741        priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION;
2742        priv->ieee80211->host_encrypt = 1;
2743        priv->ieee80211->host_decrypt = 1;
2744        priv->ieee80211->start_send_beacons = NULL;//rtl819xusb_beacon_tx;//-by amy 080604
2745        priv->ieee80211->stop_send_beacons = NULL;//rtl8192_beacon_stop;//-by amy 080604
2746        priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit;
2747        priv->ieee80211->set_chan = rtl8192_set_chan;
2748        priv->ieee80211->link_change = rtl8192_link_change;
2749        priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit;
2750        priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop;
2751        priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume;
2752        priv->ieee80211->init_wmmparam_flag = 0;
2753        priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
2754        priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc;
2755        priv->ieee80211->tx_headroom = TX_PACKET_SHIFT_BYTES;
2756        priv->ieee80211->qos_support = 1;
2757
2758        //added by WB
2759//      priv->ieee80211->SwChnlByTimerHandler = rtl8192_phy_SwChnl;
2760        priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode;
2761        priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response;
2762        priv->ieee80211->handle_beacon = rtl8192_handle_beacon;
2763        //added by david
2764        priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8192;
2765        priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xUsb;
2766        priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode;
2767        //added by amy
2768        priv->ieee80211->InitialGainHandler = InitialGain819xUsb;
2769        priv->card_type = USB;
2770#ifdef TO_DO_LIST
2771        if(Adapter->bInHctTest)
2772        {
2773                pHalData->ShortRetryLimit = 7;
2774                pHalData->LongRetryLimit = 7;
2775        }
2776#endif
2777        {
2778                priv->ShortRetryLimit = 0x30;
2779                priv->LongRetryLimit = 0x30;
2780        }
2781        priv->EarlyRxThreshold = 7;
2782        priv->enable_gpio0 = 0;
2783        priv->TransmitConfig =
2784        //      TCR_DurProcMode |       //for RTL8185B, duration setting by HW
2785        //?     TCR_DISReqQsize |
2786                (TCR_MXDMA_2048<<TCR_MXDMA_OFFSET)|  // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
2787                (priv->ShortRetryLimit<<TCR_SRL_OFFSET)|        // Short retry limit
2788                (priv->LongRetryLimit<<TCR_LRL_OFFSET) |        // Long retry limit
2789                (false ? TCR_SAT: 0);   // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
2790#ifdef TO_DO_LIST
2791        if(Adapter->bInHctTest)
2792                pHalData->ReceiveConfig =       pHalData->CSMethod |
2793                                                RCR_AMF | RCR_ADF |     //RCR_AAP |     //accept management/data
2794                                                //guangan200710
2795                                                RCR_ACF |       //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2796                                                RCR_AB | RCR_AM | RCR_APM |             //accept BC/MC/UC
2797                                                RCR_AICV | RCR_ACRC32 |                 //accept ICV/CRC error packet
2798                                                ((u32)7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2799                                                (pHalData->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
2800                                                (pHalData->EarlyRxThreshold == 7 ? RCR_OnlyErlPkt:0);
2801        else
2802
2803#endif
2804        priv->ReceiveConfig     =
2805                RCR_AMF | RCR_ADF |             //accept management/data
2806                RCR_ACF |                       //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
2807                RCR_AB | RCR_AM | RCR_APM |     //accept BC/MC/UC
2808                //RCR_AICV | RCR_ACRC32 |       //accept ICV/CRC error packet
2809                ((u32)7<<RCR_MXDMA_OFFSET)| // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
2810                (priv->EarlyRxThreshold<<RX_FIFO_THRESHOLD_SHIFT) | // Rx FIFO Threshold, 7: No Rx threshold.
2811                (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
2812
2813        priv->AcmControl = 0;
2814        priv->pFirmware = kmalloc(sizeof(rt_firmware), GFP_KERNEL);
2815        if (priv->pFirmware)
2816        memset(priv->pFirmware, 0, sizeof(rt_firmware));
2817
2818        /* rx related queue */
2819        skb_queue_head_init(&priv->rx_queue);
2820        skb_queue_head_init(&priv->skb_queue);
2821
2822        /* Tx related queue */
2823        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2824                skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]);
2825        }
2826        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2827                skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]);
2828        }
2829        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
2830                skb_queue_head_init(&priv->ieee80211->skb_drv_aggQ [i]);
2831        }
2832        priv->rf_set_chan = rtl8192_phy_SwChnl;
2833}
2834
2835//init lock here
2836static void rtl8192_init_priv_lock(struct r8192_priv* priv)
2837{
2838        spin_lock_init(&priv->tx_lock);
2839        spin_lock_init(&priv->irq_lock);//added by thomas
2840        //spin_lock_init(&priv->rf_lock);
2841        sema_init(&priv->wx_sem,1);
2842        sema_init(&priv->rf_sem,1);
2843        mutex_init(&priv->mutex);
2844}
2845
2846extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work);
2847
2848void rtl8192_irq_rx_tasklet(struct r8192_priv *priv);
2849//init tasklet and wait_queue here. only 2.6 above kernel is considered
2850#define DRV_NAME "wlan0"
2851static void rtl8192_init_priv_task(struct net_device* dev)
2852{
2853        struct r8192_priv *priv = ieee80211_priv(dev);
2854
2855#ifdef PF_SYNCTHREAD
2856        priv->priv_wq = create_workqueue(DRV_NAME,0);
2857#else
2858        priv->priv_wq = create_workqueue(DRV_NAME);
2859#endif
2860
2861        INIT_WORK(&priv->reset_wq, rtl8192_restart);
2862
2863        //INIT_DELAYED_WORK(&priv->watch_dog_wq, hal_dm_watchdog);
2864        INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback);
2865        INIT_DELAYED_WORK(&priv->txpower_tracking_wq,  dm_txpower_trackingcallback);
2866//      INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
2867        INIT_DELAYED_WORK(&priv->rfpath_check_wq,  dm_rf_pathcheck_workitemcallback);
2868        INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon);
2869        INIT_DELAYED_WORK(&priv->initialgain_operate_wq, InitialGainOperateWorkItemCallBack);
2870        //INIT_WORK(&priv->SwChnlWorkItem,  rtl8192_SwChnl_WorkItem);
2871        //INIT_WORK(&priv->SetBWModeWorkItem,  rtl8192_SetBWModeWorkItem);
2872        INIT_WORK(&priv->qos_activate, rtl8192_qos_activate);
2873
2874        tasklet_init(&priv->irq_rx_tasklet,
2875             (void(*)(unsigned long))rtl8192_irq_rx_tasklet,
2876             (unsigned long)priv);
2877}
2878
2879static void rtl8192_get_eeprom_size(struct net_device* dev)
2880{
2881        u16 curCR = 0;
2882        struct r8192_priv *priv = ieee80211_priv(dev);
2883        RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2884        curCR = read_nic_word_E(dev,EPROM_CMD);
2885        RT_TRACE(COMP_EPROM, "read from Reg EPROM_CMD(%x):%x\n", EPROM_CMD, curCR);
2886        //whether need I consider BIT5?
2887        priv->epromtype = (curCR & Cmd9346CR_9356SEL) ? EPROM_93c56 : EPROM_93c46;
2888        RT_TRACE(COMP_EPROM, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype);
2889}
2890
2891//used to swap endian. as ntohl & htonl are not necessary to swap endian, so use this instead.
2892static inline u16 endian_swap(u16* data)
2893{
2894        u16 tmp = *data;
2895        *data = (tmp >> 8) | (tmp << 8);
2896        return *data;
2897}
2898static void rtl8192_read_eeprom_info(struct net_device* dev)
2899{
2900        u16 wEPROM_ID = 0;
2901        u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x02};
2902        u8 bLoad_From_EEPOM = false;
2903        struct r8192_priv *priv = ieee80211_priv(dev);
2904        u16 tmpValue = 0;
2905        RT_TRACE(COMP_EPROM, "===========>%s()\n", __FUNCTION__);
2906        wEPROM_ID = eprom_read(dev, 0); //first read EEPROM ID out;
2907        RT_TRACE(COMP_EPROM, "EEPROM ID is 0x%x\n", wEPROM_ID);
2908
2909        if (wEPROM_ID != RTL8190_EEPROM_ID)
2910        {
2911                RT_TRACE(COMP_ERR, "EEPROM ID is invalid(is 0x%x(should be 0x%x)\n", wEPROM_ID, RTL8190_EEPROM_ID);
2912        }
2913        else
2914                bLoad_From_EEPOM = true;
2915
2916        if (bLoad_From_EEPOM)
2917        {
2918                tmpValue = eprom_read(dev, (EEPROM_VID>>1));
2919                priv->eeprom_vid = endian_swap(&tmpValue);
2920                priv->eeprom_pid = eprom_read(dev, (EEPROM_PID>>1));
2921                tmpValue = eprom_read(dev, (EEPROM_ChannelPlan>>1));
2922                priv->eeprom_ChannelPlan =((tmpValue&0xff00)>>8);
2923                priv->btxpowerdata_readfromEEPORM = true;
2924                priv->eeprom_CustomerID = eprom_read(dev, (EEPROM_Customer_ID>>1)) >>8;
2925        }
2926        else
2927        {
2928                priv->eeprom_vid = 0;
2929                priv->eeprom_pid = 0;
2930                priv->card_8192_version = VERSION_819xU_B;
2931                priv->eeprom_ChannelPlan = 0;
2932                priv->eeprom_CustomerID = 0;
2933        }
2934        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);
2935        //set channelplan from eeprom
2936        priv->ChannelPlan = priv->eeprom_ChannelPlan;
2937        if (bLoad_From_EEPOM)
2938        {
2939                int i;
2940                for (i=0; i<6; i+=2)
2941                {
2942                        u16 tmp = 0;
2943                        tmp = eprom_read(dev, (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i)>>1));
2944                        *(u16*)(&dev->dev_addr[i]) = tmp;
2945                }
2946        }
2947        else
2948        {
2949                memcpy(dev->dev_addr, bMac_Tmp_Addr, 6);
2950                //should I set IDR0 here?
2951        }
2952        RT_TRACE(COMP_EPROM, "MAC addr:%pM\n", dev->dev_addr);
2953        priv->rf_type = RTL819X_DEFAULT_RF_TYPE; //default 1T2R
2954        priv->rf_chip = RF_8256;
2955
2956        if (priv->card_8192_version == (u8)VERSION_819xU_A)
2957        {
2958                //read Tx power gain offset of legacy OFDM to HT rate
2959                if (bLoad_From_EEPOM)
2960                        priv->EEPROMTxPowerDiff = (eprom_read(dev, (EEPROM_TxPowerDiff>>1))&0xff00) >> 8;
2961                else
2962                        priv->EEPROMTxPowerDiff = EEPROM_Default_TxPower;
2963                RT_TRACE(COMP_EPROM, "TxPowerDiff:%d\n", priv->EEPROMTxPowerDiff);
2964                //read ThermalMeter from EEPROM
2965                if (bLoad_From_EEPOM)
2966                        priv->EEPROMThermalMeter = (u8)(eprom_read(dev, (EEPROM_ThermalMeter>>1))&0x00ff);
2967                else
2968                        priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
2969                RT_TRACE(COMP_EPROM, "ThermalMeter:%d\n", priv->EEPROMThermalMeter);
2970                //vivi, for tx power track
2971                priv->TSSI_13dBm = priv->EEPROMThermalMeter *100;
2972                //read antenna tx power offset of B/C/D to A from EEPROM
2973                if (bLoad_From_EEPOM)
2974                        priv->EEPROMPwDiff = (eprom_read(dev, (EEPROM_PwDiff>>1))&0x0f00)>>8;
2975                else
2976                        priv->EEPROMPwDiff = EEPROM_Default_PwDiff;
2977                RT_TRACE(COMP_EPROM, "TxPwDiff:%d\n", priv->EEPROMPwDiff);
2978                // Read CrystalCap from EEPROM
2979                if (bLoad_From_EEPOM)
2980                        priv->EEPROMCrystalCap = (eprom_read(dev, (EEPROM_CrystalCap>>1))&0x0f);
2981                else
2982                        priv->EEPROMCrystalCap = EEPROM_Default_CrystalCap;
2983                RT_TRACE(COMP_EPROM, "CrystalCap = %d\n", priv->EEPROMCrystalCap);
2984                //get per-channel Tx power level
2985                if (bLoad_From_EEPOM)
2986                        priv->EEPROM_Def_Ver = (eprom_read(dev, (EEPROM_TxPwIndex_Ver>>1))&0xff00)>>8;
2987                else
2988                        priv->EEPROM_Def_Ver = 1;
2989                RT_TRACE(COMP_EPROM, "EEPROM_DEF_VER:%d\n", priv->EEPROM_Def_Ver);
2990                if (priv->EEPROM_Def_Ver == 0) //old eeprom definition
2991                {
2992                        int i;
2993                        if (bLoad_From_EEPOM)
2994                                priv->EEPROMTxPowerLevelCCK = (eprom_read(dev, (EEPROM_TxPwIndex_CCK>>1))&0xff) >> 8;
2995                        else
2996                                priv->EEPROMTxPowerLevelCCK = 0x10;
2997                        RT_TRACE(COMP_EPROM, "CCK Tx Power Levl: 0x%02x\n", priv->EEPROMTxPowerLevelCCK);
2998                        for (i=0; i<3; i++)
2999                        {
3000                                if (bLoad_From_EEPOM)
3001                                {
3002                                        tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G+i)>>1);
3003                                        if (((EEPROM_TxPwIndex_OFDM_24G+i) % 2) == 0)
3004                                                tmpValue = tmpValue & 0x00ff;
3005                                        else
3006                                                tmpValue = (tmpValue & 0xff00) >> 8;
3007                                }
3008                                else
3009                                        tmpValue = 0x10;
3010                                priv->EEPROMTxPowerLevelOFDM24G[i] = (u8) tmpValue;
3011                                RT_TRACE(COMP_EPROM, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK);
3012                        }
3013                }//end if EEPROM_DEF_VER == 0
3014                else if (priv->EEPROM_Def_Ver == 1)
3015                {
3016                        if (bLoad_From_EEPOM)
3017                        {
3018                                tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1>>1));
3019                                tmpValue = (tmpValue & 0xff00) >> 8;
3020                        }
3021                        else
3022                                tmpValue = 0x10;
3023                        priv->EEPROMTxPowerLevelCCK_V1[0] = (u8)tmpValue;
3024
3025                        if (bLoad_From_EEPOM)
3026                                tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_CCK_V1 + 2)>>1);
3027                        else
3028                                tmpValue = 0x1010;
3029                        *((u16*)(&priv->EEPROMTxPowerLevelCCK_V1[1])) = tmpValue;
3030                        if (bLoad_From_EEPOM)
3031                                tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1>>1));
3032                        else
3033                                tmpValue = 0x1010;
3034                        *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[0])) = tmpValue;
3035                        if (bLoad_From_EEPOM)
3036                                tmpValue = eprom_read(dev, (EEPROM_TxPwIndex_OFDM_24G_V1+2)>>1);
3037                        else
3038                                tmpValue = 0x10;
3039                        priv->EEPROMTxPowerLevelOFDM24G[2] = (u8)tmpValue;
3040                }//endif EEPROM_Def_Ver == 1
3041
3042                //update HAL variables
3043                //
3044                {
3045                        int i;
3046                        for (i=0; i<14; i++)
3047                        {
3048                                if (i<=3)
3049                                        priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[0];
3050                                else if (i>=4 && i<=9)
3051                                        priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[1];
3052                                else
3053                                        priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[2];
3054                        }
3055
3056                        for (i=0; i<14; i++)
3057                        {
3058                                if (priv->EEPROM_Def_Ver == 0)
3059                                {
3060                                        if (i<=3)
3061                                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[0] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3062                                        else if (i>=4 && i<=9)
3063                                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK;
3064                                        else
3065                                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelOFDM24G[2] + (priv->EEPROMTxPowerLevelCCK - priv->EEPROMTxPowerLevelOFDM24G[1]);
3066                                }
3067                                else if (priv->EEPROM_Def_Ver == 1)
3068                                {
3069                                        if (i<=3)
3070                                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[0];
3071                                        else if (i>=4 && i<=9)
3072                                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[1];
3073                                        else
3074                                                priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK_V1[2];
3075                                }
3076                        }
3077                }//end update HAL variables
3078                priv->TxPowerDiff = priv->EEPROMPwDiff;
3079// Antenna B gain offset to antenna A, bit0~3
3080                priv->AntennaTxPwDiff[0] = (priv->EEPROMTxPowerDiff & 0xf);
3081                // Antenna C gain offset to antenna A, bit4~7
3082                priv->AntennaTxPwDiff[1] = ((priv->EEPROMTxPowerDiff & 0xf0)>>4);
3083                // CrystalCap, bit12~15
3084                priv->CrystalCap = priv->EEPROMCrystalCap;
3085                // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2
3086                // 92U does not enable TX power tracking.
3087                priv->ThermalMeter[0] = priv->EEPROMThermalMeter;
3088        }//end if VersionID == VERSION_819xU_A
3089
3090//added by vivi, for dlink led, 20080416
3091        switch(priv->eeprom_CustomerID)
3092        {
3093                case EEPROM_CID_RUNTOP:
3094                        priv->CustomerID = RT_CID_819x_RUNTOP;
3095                        break;
3096
3097                case EEPROM_CID_DLINK:
3098                        priv->CustomerID = RT_CID_DLINK;
3099                        break;
3100
3101                default:
3102                        priv->CustomerID = RT_CID_DEFAULT;
3103                        break;
3104
3105        }
3106
3107        switch(priv->CustomerID)
3108        {
3109                case RT_CID_819x_RUNTOP:
3110                        priv->LedStrategy = SW_LED_MODE2;
3111                        break;
3112
3113                case RT_CID_DLINK:
3114                        priv->LedStrategy = SW_LED_MODE4;
3115                        break;
3116
3117                default:
3118                        priv->LedStrategy = SW_LED_MODE0;
3119                        break;
3120
3121        }
3122
3123
3124        if(priv->rf_type == RF_1T2R)
3125        {
3126                RT_TRACE(COMP_EPROM, "\n1T2R config\n");
3127        }
3128        else
3129        {
3130                RT_TRACE(COMP_EPROM, "\n2T4R config\n");
3131        }
3132
3133        // 2008/01/16 MH We can only know RF type in the function. So we have to init
3134        // DIG RATR table again.
3135        init_rate_adaptive(dev);
3136        //we need init DIG RATR table here again.
3137
3138        RT_TRACE(COMP_EPROM, "<===========%s()\n", __FUNCTION__);
3139        return;
3140}
3141
3142short rtl8192_get_channel_map(struct net_device * dev)
3143{
3144        struct r8192_priv *priv = ieee80211_priv(dev);
3145        if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){
3146                printk("rtl8180_init:Error channel plan! Set to default.\n");
3147                priv->ChannelPlan= 0;
3148        }
3149        RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan);
3150
3151        rtl819x_set_channel_map(priv->ChannelPlan, priv);
3152        return 0;
3153}
3154
3155short rtl8192_init(struct net_device *dev)
3156{
3157
3158        struct r8192_priv *priv = ieee80211_priv(dev);
3159
3160        memset(&(priv->stats),0,sizeof(struct Stats));
3161        memset(priv->txqueue_to_outpipemap,0,9);
3162#ifdef PIPE12
3163        {
3164                int i=0;
3165                u8 queuetopipe[]={3,2,1,0,4,8,7,6,5};
3166                memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3167/*              for(i=0;i<9;i++)
3168                        printk("%d ",priv->txqueue_to_outpipemap[i]);
3169                printk("\n");*/
3170        }
3171#else
3172        {
3173                u8 queuetopipe[]={3,2,1,0,4,4,0,4,4};
3174                memcpy(priv->txqueue_to_outpipemap,queuetopipe,9);
3175/*              for(i=0;i<9;i++)
3176                        printk("%d ",priv->txqueue_to_outpipemap[i]);
3177                printk("\n");*/
3178        }
3179#endif
3180        rtl8192_init_priv_variable(dev);
3181        rtl8192_init_priv_lock(priv);
3182        rtl8192_init_priv_task(dev);
3183        rtl8192_get_eeprom_size(dev);
3184        rtl8192_read_eeprom_info(dev);
3185        rtl8192_get_channel_map(dev);
3186        init_hal_dm(dev);
3187        init_timer(&priv->watch_dog_timer);
3188        priv->watch_dog_timer.data = (unsigned long)dev;
3189        priv->watch_dog_timer.function = watch_dog_timer_callback;
3190        if(rtl8192_usb_initendpoints(dev)!=0){
3191                DMESG("Endopoints initialization failed");
3192                return -ENOMEM;
3193        }
3194
3195        //rtl8192_adapter_start(dev);
3196#ifdef DEBUG_EPROM
3197        dump_eprom(dev);
3198#endif
3199        return 0;
3200}
3201
3202/******************************************************************************
3203 *function:  This function actually only set RRSR, RATR and BW_OPMODE registers
3204 *           not to do all the hw config as its name says
3205 *   input:  net_device dev
3206 *  output:  none
3207 *  return:  none
3208 *  notice:  This part need to modified according to the rate set we filtered
3209 * ****************************************************************************/
3210void rtl8192_hwconfig(struct net_device* dev)
3211{
3212        u32 regRATR = 0, regRRSR = 0;
3213        u8 regBwOpMode = 0, regTmp = 0;
3214        struct r8192_priv *priv = ieee80211_priv(dev);
3215
3216// Set RRSR, RATR, and BW_OPMODE registers
3217        //
3218        switch(priv->ieee80211->mode)
3219        {
3220        case WIRELESS_MODE_B:
3221                regBwOpMode = BW_OPMODE_20MHZ;
3222                regRATR = RATE_ALL_CCK;
3223                regRRSR = RATE_ALL_CCK;
3224                break;
3225        case WIRELESS_MODE_A:
3226                regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ;
3227                regRATR = RATE_ALL_OFDM_AG;
3228                regRRSR = RATE_ALL_OFDM_AG;
3229                break;
3230        case WIRELESS_MODE_G:
3231                regBwOpMode = BW_OPMODE_20MHZ;
3232                regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3233                regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3234                break;
3235        case WIRELESS_MODE_AUTO:
3236#ifdef TO_DO_LIST
3237                if (Adapter->bInHctTest)
3238                {
3239                    regBwOpMode = BW_OPMODE_20MHZ;
3240                    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3241                    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3242                }
3243                else
3244#endif
3245                {
3246                    regBwOpMode = BW_OPMODE_20MHZ;
3247                    regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3248                    regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3249                }
3250                break;
3251        case WIRELESS_MODE_N_24G:
3252                // It support CCK rate by default.
3253                // CCK rate will be filtered out only when associated AP does not support it.
3254                regBwOpMode = BW_OPMODE_20MHZ;
3255                        regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3256                        regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
3257                break;
3258        case WIRELESS_MODE_N_5G:
3259                regBwOpMode = BW_OPMODE_5G;
3260                regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
3261                regRRSR = RATE_ALL_OFDM_AG;
3262                break;
3263        }
3264
3265        write_nic_byte(dev, BW_OPMODE, regBwOpMode);
3266        {
3267                u32 ratr_value = 0;
3268                ratr_value = regRATR;
3269                if (priv->rf_type == RF_1T2R)
3270                {
3271                        ratr_value &= ~(RATE_ALL_OFDM_2SS);
3272                }
3273                write_nic_dword(dev, RATR0, ratr_value);
3274                write_nic_byte(dev, UFWP, 1);
3275        }
3276        regTmp = read_nic_byte(dev, 0x313);
3277        regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff);
3278        write_nic_dword(dev, RRSR, regRRSR);
3279
3280        //
3281        // Set Retry Limit here
3282        //
3283        write_nic_word(dev, RETRY_LIMIT,
3284                        priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | \
3285                        priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT);
3286        // Set Contention Window here
3287
3288        // Set Tx AGC
3289
3290        // Set Tx Antenna including Feedback control
3291
3292        // Set Auto Rate fallback control
3293
3294
3295}
3296
3297
3298//InitializeAdapter and PhyCfg
3299bool rtl8192_adapter_start(struct net_device *dev)
3300{
3301        struct r8192_priv *priv = ieee80211_priv(dev);
3302        u32 dwRegRead = 0;
3303        bool init_status = true;
3304        RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__);
3305        priv->Rf_Mode = RF_OP_By_SW_3wire;
3306        //for ASIC power on sequence
3307        write_nic_byte_E(dev, 0x5f, 0x80);
3308        mdelay(50);
3309        write_nic_byte_E(dev, 0x5f, 0xf0);
3310        write_nic_byte_E(dev, 0x5d, 0x00);
3311        write_nic_byte_E(dev, 0x5e, 0x80);
3312        write_nic_byte(dev, 0x17, 0x37);
3313        mdelay(10);
3314//#ifdef TO_DO_LIST
3315        priv->pFirmware->firmware_status = FW_STATUS_0_INIT;
3316        //config CPUReset Register
3317        //Firmware Reset or not?
3318        dwRegRead = read_nic_dword(dev, CPU_GEN);
3319        if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT)
3320                dwRegRead |= CPU_GEN_SYSTEM_RESET; //do nothing here?
3321        else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY)
3322                dwRegRead |= CPU_GEN_FIRMWARE_RESET;
3323        else
3324                RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__,   priv->pFirmware->firmware_status);
3325
3326        write_nic_dword(dev, CPU_GEN, dwRegRead);
3327        //mdelay(30);
3328        //config BB.
3329        rtl8192_BBConfig(dev);
3330
3331        //Loopback mode or not
3332        priv->LoopbackMode = RTL819xU_NO_LOOPBACK;
3333//      priv->LoopbackMode = RTL819xU_MAC_LOOPBACK;
3334
3335        dwRegRead = read_nic_dword(dev, CPU_GEN);
3336        if (priv->LoopbackMode == RTL819xU_NO_LOOPBACK)
3337                dwRegRead = ((dwRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET);
3338        else if (priv->LoopbackMode == RTL819xU_MAC_LOOPBACK)
3339                dwRegRead |= CPU_CCK_LOOPBACK;
3340        else
3341                RT_TRACE(COMP_ERR, "Serious error in %s(): wrong loopback mode setting(%d)\n", __FUNCTION__,  priv->LoopbackMode);
3342
3343        write_nic_dword(dev, CPU_GEN, dwRegRead);
3344
3345        //after reset cpu, we need wait for a seconds to write in register.
3346        udelay(500);
3347
3348        //xiong add for new bitfile:usb suspend reset pin set to 1. //do we need?
3349        write_nic_byte_E(dev, 0x5f, (read_nic_byte_E(dev, 0x5f)|0x20));
3350
3351        //Set Hardware
3352        rtl8192_hwconfig(dev);
3353
3354        //turn on Tx/Rx
3355        write_nic_byte(dev, CMDR, CR_RE|CR_TE);
3356
3357        //set IDR0 here
3358        write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
3359        write_nic_word(dev, MAC4, ((u16*)(dev->dev_addr + 4))[0]);
3360
3361        //set RCR
3362        write_nic_dword(dev, RCR, priv->ReceiveConfig);
3363
3364        //Initialize Number of Reserved Pages in Firmware Queue
3365        write_nic_dword(dev, RQPN1,  NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT |\
3366                                                NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | \
3367                                                NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | \
3368                                                NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT);
3369        write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT |\
3370                                                NUM_OF_PAGE_IN_FW_QUEUE_CMD << RSVD_FW_QUEUE_PAGE_CMD_SHIFT);
3371        write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| \
3372                                                NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT
3373//                                              | NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT
3374                                                );
3375        write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK));
3376
3377        //Set AckTimeout
3378        // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily
3379        write_nic_byte(dev, ACK_TIMEOUT, 0x30);
3380
3381//      RT_TRACE(COMP_INIT, "%s():priv->ResetProgress is %d\n", __FUNCTION__,priv->ResetProgress);
3382        if(priv->ResetProgress == RESET_TYPE_NORESET)
3383        rtl8192_SetWirelessMode(dev, priv->ieee80211->mode);
3384        if(priv->ResetProgress == RESET_TYPE_NORESET){
3385        CamResetAllEntry(dev);
3386        {
3387                u8 SECR_value = 0x0;
3388                SECR_value |= SCR_TxEncEnable;
3389                SECR_value |= SCR_RxDecEnable;
3390                SECR_value |= SCR_NoSKMC;
3391                write_nic_byte(dev, SECR, SECR_value);
3392        }
3393        }
3394
3395        //Beacon related
3396        write_nic_word(dev, ATIMWND, 2);
3397        write_nic_word(dev, BCN_INTERVAL, 100);
3398
3399        {
3400#define DEFAULT_EDCA 0x005e4332
3401                int i;
3402                for (i=0; i<QOS_QUEUE_NUM; i++)
3403                write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA);
3404        }
3405#ifdef USB_RX_AGGREGATION_SUPPORT
3406        //3 For usb rx firmware aggregation control
3407        if(priv->ResetProgress == RESET_TYPE_NORESET)
3408        {
3409                u32 ulValue;
3410                PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
3411                ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
3412                                        (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
3413                /*
3414                 * If usb rx firmware aggregation is enabled,
3415                 * when anyone of three threshold conditions above is reached,
3416                 * firmware will send aggregated packet to driver.
3417                 */
3418                write_nic_dword(dev, 0x1a8, ulValue);
3419                priv->bCurrentRxAggrEnable = true;
3420        }
3421#endif
3422
3423        rtl8192_phy_configmac(dev);
3424
3425        if (priv->card_8192_version == (u8) VERSION_819xU_A)
3426        {
3427                rtl8192_phy_getTxPower(dev);
3428                rtl8192_phy_setTxPower(dev, priv->chan);
3429        }
3430
3431        //Firmware download
3432        init_status = init_firmware(dev);
3433        if(!init_status)
3434        {
3435                RT_TRACE(COMP_ERR,"ERR!!! %s(): Firmware download is failed\n", __FUNCTION__);
3436                return init_status;
3437        }
3438        RT_TRACE(COMP_INIT, "%s():after firmware download\n", __FUNCTION__);
3439        //
3440#ifdef TO_DO_LIST
3441if(Adapter->ResetProgress == RESET_TYPE_NORESET)
3442        {
3443                if(pMgntInfo->RegRfOff == TRUE)
3444                { // User disable RF via registry.
3445                        RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RegRfOff ----------\n"));
3446                        MgntActSet_RF_State(Adapter, eRfOff, RF_CHANGE_BY_SW);
3447                        // Those action will be discard in MgntActSet_RF_State because off the same state
3448                        for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3449                                PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3450                }
3451                else if(pMgntInfo->RfOffReason > RF_CHANGE_BY_PS)
3452                { // H/W or S/W RF OFF before sleep.
3453                        RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): Turn off RF for RfOffReason(%d) ----------\n", pMgntInfo->RfOffReason));
3454                        MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3455                }
3456                else
3457                {
3458                        pHalData->eRFPowerState = eRfOn;
3459                        pMgntInfo->RfOffReason = 0;
3460                        RT_TRACE((COMP_INIT|COMP_RF), DBG_LOUD, ("InitializeAdapter819xUsb(): RF is on ----------\n"));
3461                }
3462        }
3463        else
3464        {
3465                if(pHalData->eRFPowerState == eRfOff)
3466                {
3467                        MgntActSet_RF_State(Adapter, eRfOff, pMgntInfo->RfOffReason);
3468                        // Those action will be discard in MgntActSet_RF_State because off the same state
3469                        for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
3470                                PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x0);
3471                }
3472        }
3473#endif
3474        //config RF.
3475        if(priv->ResetProgress == RESET_TYPE_NORESET){
3476        rtl8192_phy_RFConfig(dev);
3477        RT_TRACE(COMP_INIT, "%s():after phy RF config\n", __FUNCTION__);
3478        }
3479
3480
3481        if(priv->ieee80211->FwRWRF)
3482                // We can force firmware to do RF-R/W
3483                priv->Rf_Mode = RF_OP_By_FW;
3484        else
3485                priv->Rf_Mode = RF_OP_By_SW_3wire;
3486
3487
3488        rtl8192_phy_updateInitGain(dev);
3489        /*--set CCK and OFDM Block "ON"--*/
3490        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1);
3491        rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1);
3492
3493        if(priv->ResetProgress == RESET_TYPE_NORESET)
3494        {
3495                //if D or C cut
3496                u8 tmpvalue = read_nic_byte(dev, 0x301);
3497                if(tmpvalue ==0x03)
3498                {
3499                        priv->bDcut = TRUE;
3500                        RT_TRACE(COMP_POWER_TRACKING, "D-cut\n");
3501                }
3502                else
3503                {
3504                        priv->bDcut = FALSE;
3505                        RT_TRACE(COMP_POWER_TRACKING, "C-cut\n");
3506                }
3507                dm_initialize_txpower_tracking(dev);
3508
3509                if(priv->bDcut == TRUE)
3510                {
3511                        u32 i, TempCCk;
3512                        u32 tmpRegA= rtl8192_QueryBBReg(dev,rOFDM0_XATxIQImbalance,bMaskDWord);
3513                //      u32 tmpRegC= rtl8192_QueryBBReg(dev,rOFDM0_XCTxIQImbalance,bMaskDWord);
3514                        for(i = 0; i<TxBBGainTableLength; i++)
3515                        {
3516                                if(tmpRegA == priv->txbbgain_table[i].txbbgain_value)
3517                                {
3518                                        priv->rfa_txpowertrackingindex= (u8)i;
3519                                        priv->rfa_txpowertrackingindex_real= (u8)i;
3520                                        priv->rfa_txpowertracking_default= priv->rfa_txpowertrackingindex;
3521                                        break;
3522                                }
3523                        }
3524
3525                        TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
3526
3527                        for(i=0 ; i<CCKTxBBGainTableLength ; i++)
3528                        {
3529
3530                                if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0])
3531                                {
3532                                        priv->cck_present_attentuation_20Mdefault=(u8) i;
3533                                        break;
3534                                }
3535                        }
3536                        priv->cck_present_attentuation_40Mdefault= 0;
3537                        priv->cck_present_attentuation_difference= 0;
3538                        priv->cck_present_attentuation = priv->cck_present_attentuation_20Mdefault;
3539
3540        //              pMgntInfo->bTXPowerTracking = FALSE;//TEMPLY DISABLE
3541                }
3542        }
3543        write_nic_byte(dev, 0x87, 0x0);
3544
3545
3546        return init_status;
3547}
3548
3549/* this configures registers for beacon tx and enables it via
3550 * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might
3551 * be used to stop beacon transmission
3552 */
3553/***************************************************************************
3554    -------------------------------NET STUFF---------------------------
3555***************************************************************************/
3556
3557static struct net_device_stats *rtl8192_stats(struct net_device *dev)
3558{
3559        struct r8192_priv *priv = ieee80211_priv(dev);
3560
3561        return &priv->ieee80211->stats;
3562}
3563
3564bool
3565HalTxCheckStuck819xUsb(
3566        struct net_device *dev
3567        )
3568{
3569        struct r8192_priv *priv = ieee80211_priv(dev);
3570        u16             RegTxCounter = read_nic_word(dev, 0x128);
3571        bool            bStuck = FALSE;
3572        RT_TRACE(COMP_RESET,"%s():RegTxCounter is %d,TxCounter is %d\n",__FUNCTION__,RegTxCounter,priv->TxCounter);
3573        if(priv->TxCounter==RegTxCounter)
3574                bStuck = TRUE;
3575
3576        priv->TxCounter = RegTxCounter;
3577
3578        return bStuck;
3579}
3580
3581/*
3582*       <Assumption: RT_TX_SPINLOCK is acquired.>
3583*       First added: 2006.11.19 by emily
3584*/
3585RESET_TYPE
3586TxCheckStuck(struct net_device *dev)
3587{
3588        struct r8192_priv *priv = ieee80211_priv(dev);
3589        u8                      QueueID;
3590//      PRT_TCB                 pTcb;
3591//      u8                      ResetThreshold;
3592        bool                    bCheckFwTxCnt = false;
3593        //unsigned long flags;
3594
3595        //
3596        // Decide Stuch threshold according to current power save mode
3597        //
3598
3599//     RT_TRACE(COMP_RESET, " ==> TxCheckStuck()\n");
3600//           PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
3601//           spin_lock_irqsave(&priv->ieee80211->lock,flags);
3602             for (QueueID = 0; QueueID<=BEACON_QUEUE;QueueID ++)
3603             {
3604                        if(QueueID == TXCMD_QUEUE)
3605                         continue;
3606#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
3607                        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))
3608#else
3609                        if((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0)  && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0))
3610#endif
3611                                continue;
3612
3613                     bCheckFwTxCnt = true;
3614             }
3615//           PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
3616//      spin_unlock_irqrestore(&priv->ieee80211->lock,flags);
3617//      RT_TRACE(COMP_RESET,"bCheckFwTxCnt is %d\n",bCheckFwTxCnt);
3618        if(bCheckFwTxCnt)
3619        {
3620                if(HalTxCheckStuck819xUsb(dev))
3621                {
3622                        RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no Tx condition! \n");
3623                        return RESET_TYPE_SILENT;
3624                }
3625        }
3626        return RESET_TYPE_NORESET;
3627}
3628
3629bool
3630HalRxCheckStuck819xUsb(struct net_device *dev)
3631{
3632        u16     RegRxCounter = read_nic_word(dev, 0x130);
3633        struct r8192_priv *priv = ieee80211_priv(dev);
3634        bool bStuck = FALSE;
3635        static u8       rx_chk_cnt = 0;
3636        RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter);
3637        // If rssi is small, we should check rx for long time because of bad rx.
3638        // or maybe it will continuous silent reset every 2 seconds.
3639        rx_chk_cnt++;
3640        if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5))
3641        {
3642                rx_chk_cnt = 0; //high rssi, check rx stuck right now.
3643        }
3644        else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) &&
3645                ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) ||
3646                (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) )
3647        {
3648                if(rx_chk_cnt < 2)
3649                {
3650                        return bStuck;
3651                }
3652                else
3653                {
3654                        rx_chk_cnt = 0;
3655                }
3656        }
3657        else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) ||
3658                (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) &&
3659                priv->undecorated_smoothed_pwdb >= VeryLowRSSI)
3660        {
3661                if(rx_chk_cnt < 4)
3662                {
3663                        //DbgPrint("RSSI < %d && RSSI >= %d, no check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3664                        return bStuck;
3665                }
3666                else
3667                {
3668                        rx_chk_cnt = 0;
3669                        //DbgPrint("RSSI < %d && RSSI >= %d, check this time \n", RateAdaptiveTH_Low, VeryLowRSSI);
3670                }
3671        }
3672        else
3673        {
3674                if(rx_chk_cnt < 8)
3675                {
3676                        //DbgPrint("RSSI <= %d, no check this time \n", VeryLowRSSI);
3677                        return bStuck;
3678                }
3679                else
3680                {
3681                        rx_chk_cnt = 0;
3682                        //DbgPrint("RSSI <= %d, check this time \n", VeryLowRSSI);
3683                }
3684        }
3685
3686        if(priv->RxCounter==RegRxCounter)
3687                bStuck = TRUE;
3688
3689        priv->RxCounter = RegRxCounter;
3690
3691        return bStuck;
3692}
3693
3694RESET_TYPE
3695RxCheckStuck(struct net_device *dev)
3696{
3697        struct r8192_priv *priv = ieee80211_priv(dev);
3698        //int                     i;
3699        bool        bRxCheck = FALSE;
3700
3701//       RT_TRACE(COMP_RESET," ==> RxCheckStuck()\n");
3702        //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK);
3703
3704         if(priv->IrpPendingCount > 1)
3705                bRxCheck = TRUE;
3706       //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK);
3707
3708//       RT_TRACE(COMP_RESET,"bRxCheck is %d \n",bRxCheck);
3709        if(bRxCheck)
3710        {
3711                if(HalRxCheckStuck819xUsb(dev))
3712                {
3713                        RT_TRACE(COMP_RESET, "RxStuck Condition\n");
3714                        return RESET_TYPE_SILENT;
3715                }
3716        }
3717        return RESET_TYPE_NORESET;
3718}
3719
3720
3721/**
3722*       This function is called by Checkforhang to check whether we should ask OS to reset driver
3723*
3724*       \param pAdapter The adapter context for this miniport
3725*
3726*       Note:NIC with USB interface sholud not call this function because we cannot scan descriptor
3727*       to judge whether there is tx stuck.
3728*       Note: This function may be required to be rewrite for Vista OS.
3729*       <<<Assumption: Tx spinlock has been acquired >>>
3730*
3731*       8185 and 8185b does not implement this function. This is added by Emily at 2006.11.24
3732*/
3733RESET_TYPE
3734rtl819x_ifcheck_resetornot(struct net_device *dev)
3735{
3736        struct r8192_priv *priv = ieee80211_priv(dev);
3737        RESET_TYPE      TxResetType = RESET_TYPE_NORESET;
3738        RESET_TYPE      RxResetType = RESET_TYPE_NORESET;
3739        RT_RF_POWER_STATE       rfState;
3740
3741        rfState = priv->ieee80211->eRFPowerState;
3742
3743        TxResetType = TxCheckStuck(dev);
3744        if( rfState != eRfOff ||
3745                /*ADAPTER_TEST_STATUS_FLAG(Adapter, ADAPTER_STATUS_FW_DOWNLOAD_FAILURE)) &&*/
3746                (priv->ieee80211->iw_mode != IW_MODE_ADHOC))
3747        {
3748                // If driver is in the status of firmware download failure , driver skips RF initialization and RF is
3749                // in turned off state. Driver should check whether Rx stuck and do silent reset. And
3750                // if driver is in firmware download failure status, driver should initialize RF in the following
3751                // silent reset procedure Emily, 2008.01.21
3752
3753                // Driver should not check RX stuck in IBSS mode because it is required to
3754                // set Check BSSID in order to send beacon, however, if check BSSID is
3755                // set, STA cannot hear any packet a all. Emily, 2008.04.12
3756                RxResetType = RxCheckStuck(dev);
3757        }
3758        if(TxResetType==RESET_TYPE_NORMAL || RxResetType==RESET_TYPE_NORMAL)
3759                return RESET_TYPE_NORMAL;
3760        else if(TxResetType==RESET_TYPE_SILENT || RxResetType==RESET_TYPE_SILENT){
3761                RT_TRACE(COMP_RESET,"%s():silent reset\n",__FUNCTION__);
3762                return RESET_TYPE_SILENT;
3763        }
3764        else
3765                return RESET_TYPE_NORESET;
3766
3767}
3768
3769void rtl8192_cancel_deferred_work(struct r8192_priv* priv);
3770int _rtl8192_up(struct net_device *dev);
3771int rtl8192_close(struct net_device *dev);
3772
3773
3774
3775void
3776CamRestoreAllEntry(     struct net_device *dev)
3777{
3778        u8 EntryId = 0;
3779        struct r8192_priv *priv = ieee80211_priv(dev);
3780        u8*     MacAddr = priv->ieee80211->current_network.bssid;
3781
3782        static u8       CAM_CONST_ADDR[4][6] = {
3783                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
3784                {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
3785                {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
3786                {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}};
3787        static u8       CAM_CONST_BROAD[] =
3788                {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3789
3790        RT_TRACE(COMP_SEC, "CamRestoreAllEntry: \n");
3791
3792
3793        if ((priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP40)||
3794            (priv->ieee80211->pairwise_key_type == KEY_TYPE_WEP104))
3795        {
3796
3797                for(EntryId=0; EntryId<4; EntryId++)
3798                {
3799                        {
3800                                MacAddr = CAM_CONST_ADDR[EntryId];
3801                                setKey(dev,
3802                                                EntryId ,
3803                                                EntryId,
3804                                                priv->ieee80211->pairwise_key_type,
3805                                                MacAddr,
3806                                                0,
3807                                                NULL);
3808                        }
3809                }
3810
3811        }
3812        else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_TKIP)
3813        {
3814
3815                {
3816                        if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3817                                setKey(dev,
3818                                                4,
3819                                                0,
3820                                                priv->ieee80211->pairwise_key_type,
3821                                                (u8*)dev->dev_addr,
3822                                                0,
3823                                                NULL);
3824                        else
3825                                setKey(dev,
3826                                                4,
3827                                                0,
3828                                                priv->ieee80211->pairwise_key_type,
3829                                                MacAddr,
3830                                                0,
3831                                                NULL);
3832                }
3833        }
3834        else if(priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)
3835        {
3836
3837                {
3838                        if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3839                                setKey(dev,
3840                                                4,
3841                                                0,
3842                                                priv->ieee80211->pairwise_key_type,
3843                                                (u8*)dev->dev_addr,
3844                                                0,
3845                                                NULL);
3846                        else
3847                                setKey(dev,
3848                                                4,
3849                                                0,
3850                                                priv->ieee80211->pairwise_key_type,
3851                                                MacAddr,
3852                                                0,
3853                                                NULL);
3854                }
3855        }
3856
3857
3858
3859        if(priv->ieee80211->group_key_type == KEY_TYPE_TKIP)
3860        {
3861                MacAddr = CAM_CONST_BROAD;
3862                for(EntryId=1 ; EntryId<4 ; EntryId++)
3863                {
3864                        {
3865                                setKey(dev,
3866                                                EntryId,
3867                                                EntryId,
3868                                                priv->ieee80211->group_key_type,
3869                                                MacAddr,
3870                                                0,
3871                                                NULL);
3872                        }
3873                }
3874                if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3875                                setKey(dev,
3876                                                0,
3877                                                0,
3878                                                priv->ieee80211->group_key_type,
3879                                                CAM_CONST_ADDR[0],
3880                                                0,
3881                                                NULL);
3882        }
3883        else if(priv->ieee80211->group_key_type == KEY_TYPE_CCMP)
3884        {
3885                MacAddr = CAM_CONST_BROAD;
3886                for(EntryId=1; EntryId<4 ; EntryId++)
3887                {
3888                        {
3889                                setKey(dev,
3890                                                EntryId ,
3891                                                EntryId,
3892                                                priv->ieee80211->group_key_type,
3893                                                MacAddr,
3894                                                0,
3895                                                NULL);
3896                        }
3897                }
3898
3899                if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
3900                                setKey(dev,
3901                                                0 ,
3902                                                0,
3903                                                priv->ieee80211->group_key_type,
3904                                                CAM_CONST_ADDR[0],
3905                                                0,
3906                                                NULL);
3907        }
3908}
3909//////////////////////////////////////////////////////////////
3910// This function is used to fix Tx/Rx stop bug temporarily.
3911// This function will do "system reset" to NIC when Tx or Rx is stuck.
3912// The method checking Tx/Rx stuck of this function is supported by FW,
3913// which reports Tx and Rx counter to register 0x128 and 0x130.
3914//////////////////////////////////////////////////////////////
3915void
3916rtl819x_ifsilentreset(struct net_device *dev)
3917{
3918        //OCTET_STRING asocpdu;
3919        struct r8192_priv *priv = ieee80211_priv(dev);
3920        u8      reset_times = 0;
3921        int reset_status = 0;
3922        struct ieee80211_device *ieee = priv->ieee80211;
3923
3924
3925        // 2007.07.20. If we need to check CCK stop, please uncomment this line.
3926        //bStuck = Adapter->HalFunc.CheckHWStopHandler(Adapter);
3927
3928        if(priv->ResetProgress==RESET_TYPE_NORESET)
3929        {
3930RESET_START:
3931
3932                RT_TRACE(COMP_RESET,"=========>Reset progress!! \n");
3933
3934                // Set the variable for reset.
3935                priv->ResetProgress = RESET_TYPE_SILENT;
3936//              rtl8192_close(dev);
3937                down(&priv->wx_sem);
3938                if(priv->up == 0)
3939                {
3940                        RT_TRACE(COMP_ERR,"%s():the driver is not up! return\n",__FUNCTION__);
3941                        up(&priv->wx_sem);
3942                        return ;
3943                }
3944                priv->up = 0;
3945                RT_TRACE(COMP_RESET,"%s():======>start to down the driver\n",__FUNCTION__);
3946//              if(!netif_queue_stopped(dev))
3947//                      netif_stop_queue(dev);
3948
3949                rtl8192_rtx_disable(dev);
3950                rtl8192_cancel_deferred_work(priv);
3951                deinit_hal_dm(dev);
3952                del_timer_sync(&priv->watch_dog_timer);
3953
3954                ieee->sync_scan_hurryup = 1;
3955                if(ieee->state == IEEE80211_LINKED)
3956                {
3957                        down(&ieee->wx_sem);
3958                        printk("ieee->state is IEEE80211_LINKED\n");
3959                        ieee80211_stop_send_beacons(priv->ieee80211);
3960                        del_timer_sync(&ieee->associate_timer);
3961                        cancel_delayed_work(&ieee->associate_retry_wq);
3962                        ieee80211_stop_scan(ieee);
3963                        netif_carrier_off(dev);
3964                        up(&ieee->wx_sem);
3965                }
3966                else{
3967                        printk("ieee->state is NOT LINKED\n");
3968                        ieee80211_softmac_stop_protocol(priv->ieee80211);                       }
3969                up(&priv->wx_sem);
3970                RT_TRACE(COMP_RESET,"%s():<==========down process is finished\n",__FUNCTION__);
3971        //rtl8192_irq_disable(dev);
3972                RT_TRACE(COMP_RESET,"%s():===========>start to up the driver\n",__FUNCTION__);
3973                reset_status = _rtl8192_up(dev);
3974
3975                RT_TRACE(COMP_RESET,"%s():<===========up process is finished\n",__FUNCTION__);
3976                if(reset_status == -EAGAIN)
3977                {
3978                        if(reset_times < 3)
3979                        {
3980                                reset_times++;
3981                                goto RESET_START;
3982                        }
3983                        else
3984                        {
3985                                RT_TRACE(COMP_ERR," ERR!!! %s():  Reset Failed!!\n", __FUNCTION__);
3986                        }
3987                }
3988                ieee->is_silent_reset = 1;
3989                EnableHWSecurityConfig8192(dev);
3990                if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA)
3991                {
3992                        ieee->set_chan(ieee->dev, ieee->current_network.channel);
3993
3994                        queue_work(ieee->wq, &ieee->associate_complete_wq);
3995
3996                }
3997                else if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_ADHOC)
3998                {
3999                        ieee->set_chan(ieee->dev, ieee->current_network.channel);
4000                        ieee->link_change(ieee->dev);
4001
4002                //      notify_wx_assoc_event(ieee);
4003
4004                        ieee80211_start_send_beacons(ieee);
4005
4006                        if (ieee->data_hard_resume)
4007                                ieee->data_hard_resume(ieee->dev);
4008                        netif_carrier_on(ieee->dev);
4009                }
4010
4011                CamRestoreAllEntry(dev);
4012
4013                priv->ResetProgress = RESET_TYPE_NORESET;
4014                priv->reset_count++;
4015
4016                priv->bForcedSilentReset =false;
4017                priv->bResetInProgress = false;
4018
4019                // For test --> force write UFWP.
4020                write_nic_byte(dev, UFWP, 1);
4021                RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", priv->reset_count);
4022        }
4023}
4024
4025void CAM_read_entry(
4026        struct net_device *dev,
4027        u32                     iIndex
4028)
4029{
4030        u32 target_command=0;
4031         u32 target_content=0;
4032         u8 entry_i=0;
4033         u32 ulStatus;
4034        s32 i=100;
4035//      printk("=======>start read CAM\n");
4036        for(entry_i=0;entry_i<CAM_CONTENT_COUNT;entry_i++)
4037        {
4038        // polling bit, and No Write enable, and address
4039                target_command= entry_i+CAM_CONTENT_COUNT*iIndex;
4040                target_command= target_command | BIT31;
4041
4042        //Check polling bit is clear
4043//      mdelay(1);
4044                while((i--)>=0)
4045                {
4046                        ulStatus = read_nic_dword(dev, RWCAM);
4047                        if(ulStatus & BIT31){
4048                                continue;
4049                        }
4050                        else{
4051                                break;
4052                        }
4053                }
4054                write_nic_dword(dev, RWCAM, target_command);
4055                RT_TRACE(COMP_SEC,"CAM_read_entry(): WRITE A0: %x \n",target_command);
4056         //     printk("CAM_read_entry(): WRITE A0: %lx \n",target_command);
4057                target_content = read_nic_dword(dev, RCAMO);
4058                RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x \n",target_content);
4059         //     printk("CAM_read_entry(): WRITE A8: %lx \n",target_content);
4060        }
4061        printk("\n");
4062}
4063
4064void rtl819x_update_rxcounts(
4065        struct r8192_priv *priv,
4066        u32* TotalRxBcnNum,
4067        u32* TotalRxDataNum
4068)
4069{
4070        u16                     SlotIndex;
4071        u8                      i;
4072
4073        *TotalRxBcnNum = 0;
4074        *TotalRxDataNum = 0;
4075
4076        SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum);
4077        priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod;
4078        priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod;
4079        for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){
4080                *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i];
4081                *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i];
4082        }
4083}
4084
4085
4086extern  void    rtl819x_watchdog_wqcallback(struct work_struct *work)
4087{
4088        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
4089       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq);
4090       struct net_device *dev = priv->ieee80211->dev;
4091        struct ieee80211_device* ieee = priv->ieee80211;
4092        RESET_TYPE      ResetType = RESET_TYPE_NORESET;
4093        static u8       check_reset_cnt=0;
4094        bool bBusyTraffic = false;
4095
4096        if(!priv->up)
4097                return;
4098        hal_dm_watchdog(dev);
4099
4100        {//to get busy traffic condition
4101                if(ieee->state == IEEE80211_LINKED)
4102                {
4103                        if(     ieee->LinkDetectInfo.NumRxOkInPeriod> 666 ||
4104                                ieee->LinkDetectInfo.NumTxOkInPeriod> 666 ) {
4105                                bBusyTraffic = true;
4106                        }
4107                        ieee->LinkDetectInfo.NumRxOkInPeriod = 0;
4108                        ieee->LinkDetectInfo.NumTxOkInPeriod = 0;
4109                        ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
4110                }
4111        }
4112        //added by amy for AP roaming
4113        {
4114                if(priv->ieee80211->state == IEEE80211_LINKED && priv->ieee80211->iw_mode == IW_MODE_INFRA)
4115                {
4116                        u32     TotalRxBcnNum = 0;
4117                        u32     TotalRxDataNum = 0;
4118
4119                        rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum);
4120                        if((TotalRxBcnNum+TotalRxDataNum) == 0)
4121                        {
4122                                #ifdef TODO
4123                                if(rfState == eRfOff)
4124                                        RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__);
4125                                #endif
4126                                printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__);
4127                        //      Dot11d_Reset(dev);
4128                                priv->ieee80211->state = IEEE80211_ASSOCIATING;
4129                                notify_wx_assoc_event(priv->ieee80211);
4130                                RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid);
4131                                priv->ieee80211->link_change(dev);
4132                                queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
4133
4134                        }
4135                }
4136                priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod=0;
4137                priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod=0;
4138        }
4139//      CAM_read_entry(dev,4);
4140        //check if reset the driver
4141        if(check_reset_cnt++ >= 3)
4142        {
4143                ResetType = rtl819x_ifcheck_resetornot(dev);
4144                check_reset_cnt = 3;
4145                //DbgPrint("Start to check silent reset\n");
4146        }
4147        //      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);
4148        if( (priv->force_reset) || (priv->ResetProgress==RESET_TYPE_NORESET &&
4149                (priv->bForcedSilentReset ||
4150                (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT)))) // This is control by OID set in Pomelo
4151        {
4152                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);
4153                rtl819x_ifsilentreset(dev);
4154        }
4155        priv->force_reset = false;
4156        priv->bForcedSilentReset = false;
4157        priv->bResetInProgress = false;
4158        RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n");
4159
4160}
4161
4162void watch_dog_timer_callback(unsigned long data)
4163{
4164        struct r8192_priv *priv = ieee80211_priv((struct net_device *) data);
4165        //printk("===============>watch_dog  timer\n");
4166        queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq, 0);
4167        mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME));
4168}
4169int _rtl8192_up(struct net_device *dev)
4170{
4171        struct r8192_priv *priv = ieee80211_priv(dev);
4172        //int i;
4173        int init_status = 0;
4174        priv->up=1;
4175        priv->ieee80211->ieee_up=1;
4176        RT_TRACE(COMP_INIT, "Bringing up iface");
4177        init_status = rtl8192_adapter_start(dev);
4178        if(!init_status)
4179        {
4180                RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n", __FUNCTION__);
4181                priv->up=priv->ieee80211->ieee_up = 0;
4182                return -EAGAIN;
4183        }
4184        RT_TRACE(COMP_INIT, "start adapter finished\n");
4185        rtl8192_rx_enable(dev);
4186//      rtl8192_tx_enable(dev);
4187        if(priv->ieee80211->state != IEEE80211_LINKED)
4188        ieee80211_softmac_start_protocol(priv->ieee80211);
4189        ieee80211_reset_queue(priv->ieee80211);
4190        watch_dog_timer_callback((unsigned long) dev);
4191        if(!netif_queue_stopped(dev))
4192                netif_start_queue(dev);
4193        else
4194                netif_wake_queue(dev);
4195
4196        return 0;
4197}
4198
4199
4200int rtl8192_open(struct net_device *dev)
4201{
4202        struct r8192_priv *priv = ieee80211_priv(dev);
4203        int ret;
4204        down(&priv->wx_sem);
4205        ret = rtl8192_up(dev);
4206        up(&priv->wx_sem);
4207        return ret;
4208
4209}
4210
4211
4212int rtl8192_up(struct net_device *dev)
4213{
4214        struct r8192_priv *priv = ieee80211_priv(dev);
4215
4216        if (priv->up == 1) return -1;
4217
4218        return _rtl8192_up(dev);
4219}
4220
4221
4222int rtl8192_close(struct net_device *dev)
4223{
4224        struct r8192_priv *priv = ieee80211_priv(dev);
4225        int ret;
4226
4227        down(&priv->wx_sem);
4228
4229        ret = rtl8192_down(dev);
4230
4231        up(&priv->wx_sem);
4232
4233        return ret;
4234
4235}
4236
4237int rtl8192_down(struct net_device *dev)
4238{
4239        struct r8192_priv *priv = ieee80211_priv(dev);
4240        int i;
4241
4242        if (priv->up == 0) return -1;
4243
4244        priv->up=0;
4245        priv->ieee80211->ieee_up = 0;
4246        RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__);
4247/* FIXME */
4248        if (!netif_queue_stopped(dev))
4249                netif_stop_queue(dev);
4250
4251        rtl8192_rtx_disable(dev);
4252        //rtl8192_irq_disable(dev);
4253
4254 /* Tx related queue release */
4255        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4256                skb_queue_purge(&priv->ieee80211->skb_waitQ [i]);
4257        }
4258        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4259                skb_queue_purge(&priv->ieee80211->skb_aggQ [i]);
4260        }
4261
4262        for(i = 0; i < MAX_QUEUE_SIZE; i++) {
4263                skb_queue_purge(&priv->ieee80211->skb_drv_aggQ [i]);
4264        }
4265
4266        //as cancel_delayed_work will del work->timer, so if work is not definedas struct delayed_work, it will corrupt
4267//      flush_scheduled_work();
4268        rtl8192_cancel_deferred_work(priv);
4269        deinit_hal_dm(dev);
4270        del_timer_sync(&priv->watch_dog_timer);
4271
4272
4273        ieee80211_softmac_stop_protocol(priv->ieee80211);
4274        memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list));
4275        RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__);
4276
4277                return 0;
4278}
4279
4280
4281void rtl8192_commit(struct net_device *dev)
4282{
4283        struct r8192_priv *priv = ieee80211_priv(dev);
4284        int reset_status = 0;
4285        //u8 reset_times = 0;
4286        if (priv->up == 0) return ;
4287        priv->up = 0;
4288
4289        rtl8192_cancel_deferred_work(priv);
4290        del_timer_sync(&priv->watch_dog_timer);
4291        //cancel_delayed_work(&priv->SwChnlWorkItem);
4292
4293        ieee80211_softmac_stop_protocol(priv->ieee80211);
4294
4295        //rtl8192_irq_disable(dev);
4296        rtl8192_rtx_disable(dev);
4297        reset_status = _rtl8192_up(dev);
4298
4299}
4300
4301/*
4302void rtl8192_restart(struct net_device *dev)
4303{
4304        struct r8192_priv *priv = ieee80211_priv(dev);
4305*/
4306void rtl8192_restart(struct work_struct *work)
4307{
4308        struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq);
4309        struct net_device *dev = priv->ieee80211->dev;
4310
4311        down(&priv->wx_sem);
4312
4313        rtl8192_commit(dev);
4314
4315        up(&priv->wx_sem);
4316}
4317
4318static void r8192_set_multicast(struct net_device *dev)
4319{
4320        struct r8192_priv *priv = ieee80211_priv(dev);
4321        short promisc;
4322
4323        //down(&priv->wx_sem);
4324
4325        /* FIXME FIXME */
4326
4327        promisc = (dev->flags & IFF_PROMISC) ? 1:0;
4328
4329        if (promisc != priv->promisc)
4330        //      rtl8192_commit(dev);
4331
4332        priv->promisc = promisc;
4333
4334        //schedule_work(&priv->reset_wq);
4335        //up(&priv->wx_sem);
4336}
4337
4338
4339int r8192_set_mac_adr(struct net_device *dev, void *mac)
4340{
4341        struct r8192_priv *priv = ieee80211_priv(dev);
4342        struct sockaddr *addr = mac;
4343
4344        down(&priv->wx_sem);
4345
4346        memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
4347
4348        schedule_work(&priv->reset_wq);
4349        up(&priv->wx_sem);
4350
4351        return 0;
4352}
4353
4354/* based on ipw2200 driver */
4355int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
4356{
4357        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4358        struct iwreq *wrq = (struct iwreq *)rq;
4359        int ret=-1;
4360        struct ieee80211_device *ieee = priv->ieee80211;
4361        u32 key[4];
4362        u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
4363        struct iw_point *p = &wrq->u.data;
4364        struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer;
4365
4366        down(&priv->wx_sem);
4367
4368
4369     if (p->length < sizeof(struct ieee_param) || !p->pointer){
4370             ret = -EINVAL;
4371             goto out;
4372        }
4373
4374     ipw = kmalloc(p->length, GFP_KERNEL);
4375     if (ipw == NULL){
4376             ret = -ENOMEM;
4377             goto out;
4378     }
4379     if (copy_from_user(ipw, p->pointer, p->length)) {
4380                kfree(ipw);
4381            ret = -EFAULT;
4382            goto out;
4383        }
4384
4385        switch (cmd) {
4386            case RTL_IOCTL_WPA_SUPPLICANT:
4387        //parse here for HW security
4388                        if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION)
4389                        {
4390                                if (ipw->u.crypt.set_tx)
4391                                {
4392                                        if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4393                                                ieee->pairwise_key_type = KEY_TYPE_CCMP;
4394                                        else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4395                                                ieee->pairwise_key_type = KEY_TYPE_TKIP;
4396                                        else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4397                                        {
4398                                                if (ipw->u.crypt.key_len == 13)
4399                                                        ieee->pairwise_key_type = KEY_TYPE_WEP104;
4400                                                else if (ipw->u.crypt.key_len == 5)
4401                                                        ieee->pairwise_key_type = KEY_TYPE_WEP40;
4402                                        }
4403                                        else
4404                                                ieee->pairwise_key_type = KEY_TYPE_NA;
4405
4406                                        if (ieee->pairwise_key_type)
4407                                        {
4408                                                memcpy((u8*)key, ipw->u.crypt.key, 16);
4409                                                EnableHWSecurityConfig8192(dev);
4410                                        //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!
4411                                        //added by WB.
4412                                                setKey(dev, 4, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4413                                                if (ieee->auth_mode != 2)
4414                                                setKey(dev, ipw->u.crypt.idx, ipw->u.crypt.idx, ieee->pairwise_key_type, (u8*)ieee->ap_mac_addr, 0, key);
4415                                        }
4416                                }
4417                                else //if (ipw->u.crypt.idx) //group key use idx > 0
4418                                {
4419                                        memcpy((u8*)key, ipw->u.crypt.key, 16);
4420                                        if (strcmp(ipw->u.crypt.alg, "CCMP") == 0)
4421                                                ieee->group_key_type= KEY_TYPE_CCMP;
4422                                        else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0)
4423                                                ieee->group_key_type = KEY_TYPE_TKIP;
4424                                        else if (strcmp(ipw->u.crypt.alg, "WEP") == 0)
4425                                        {
4426                                                if (ipw->u.crypt.key_len == 13)
4427                                                        ieee->group_key_type = KEY_TYPE_WEP104;
4428                                                else if (ipw->u.crypt.key_len == 5)
4429                                                        ieee->group_key_type = KEY_TYPE_WEP40;
4430                                        }
4431                                        else
4432                                                ieee->group_key_type = KEY_TYPE_NA;
4433
4434                                        if (ieee->group_key_type)
4435                                        {
4436                                                        setKey( dev,
4437                                                                ipw->u.crypt.idx,
4438                                                                ipw->u.crypt.idx,               //KeyIndex
4439                                                                ieee->group_key_type,   //KeyType
4440                                                                broadcast_addr, //MacAddr
4441                                                                0,              //DefaultKey
4442                                                                key);           //KeyContent
4443                                        }
4444                                }
4445                        }
4446#ifdef JOHN_HWSEC_DEBUG
4447                //john's test 0711
4448                printk("@@ wrq->u pointer = ");
4449                for(i=0;i<wrq->u.data.length;i++){
4450                        if(i%10==0) printk("\n");
4451                        printk( "%8x|", ((u32*)wrq->u.data.pointer)[i] );
4452                }
4453                printk("\n");
4454#endif /*JOHN_HWSEC_DEBUG*/
4455                ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
4456                break;
4457
4458            default:
4459                ret = -EOPNOTSUPP;
4460                break;
4461        }
4462        kfree(ipw);
4463        ipw = NULL;
4464out:
4465        up(&priv->wx_sem);
4466        return ret;
4467}
4468
4469u8 HwRateToMRate90(bool bIsHT, u8 rate)
4470{
4471        u8  ret_rate = 0xff;
4472
4473        if(!bIsHT) {
4474                switch(rate) {
4475                        case DESC90_RATE1M:   ret_rate = MGN_1M;         break;
4476                        case DESC90_RATE2M:   ret_rate = MGN_2M;         break;
4477                        case DESC90_RATE5_5M: ret_rate = MGN_5_5M;       break;
4478                        case DESC90_RATE11M:  ret_rate = MGN_11M;        break;
4479                        case DESC90_RATE6M:   ret_rate = MGN_6M;         break;
4480                        case DESC90_RATE9M:   ret_rate = MGN_9M;         break;
4481                        case DESC90_RATE12M:  ret_rate = MGN_12M;        break;
4482                        case DESC90_RATE18M:  ret_rate = MGN_18M;        break;
4483                        case DESC90_RATE24M:  ret_rate = MGN_24M;        break;
4484                        case DESC90_RATE36M:  ret_rate = MGN_36M;        break;
4485                        case DESC90_RATE48M:  ret_rate = MGN_48M;        break;
4486                        case DESC90_RATE54M:  ret_rate = MGN_54M;        break;
4487
4488                        default:
4489                                ret_rate = 0xff;
4490                                RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT);
4491                                break;
4492                }
4493
4494        } else {
4495                switch(rate) {
4496                        case DESC90_RATEMCS0:   ret_rate = MGN_MCS0;    break;
4497                        case DESC90_RATEMCS1:   ret_rate = MGN_MCS1;    break;
4498                        case DESC90_RATEMCS2:   ret_rate = MGN_MCS2;    break;
4499                        case DESC90_RATEMCS3:   ret_rate = MGN_MCS3;    break;
4500                        case DESC90_RATEMCS4:   ret_rate = MGN_MCS4;    break;
4501                        case DESC90_RATEMCS5:   ret_rate = MGN_MCS5;    break;
4502                        case DESC90_RATEMCS6:   ret_rate = MGN_MCS6;    break;
4503                        case DESC90_RATEMCS7:   ret_rate = MGN_MCS7;    break;
4504                        case DESC90_RATEMCS8:   ret_rate = MGN_MCS8;    break;
4505                        case DESC90_RATEMCS9:   ret_rate = MGN_MCS9;    break;
4506                        case DESC90_RATEMCS10:  ret_rate = MGN_MCS10;   break;
4507                        case DESC90_RATEMCS11:  ret_rate = MGN_MCS11;   break;
4508                        case DESC90_RATEMCS12:  ret_rate = MGN_MCS12;   break;
4509                        case DESC90_RATEMCS13:  ret_rate = MGN_MCS13;   break;
4510                        case DESC90_RATEMCS14:  ret_rate = MGN_MCS14;   break;
4511                        case DESC90_RATEMCS15:  ret_rate = MGN_MCS15;   break;
4512                        case DESC90_RATEMCS32:  ret_rate = (0x80|0x20); break;
4513
4514                        default:
4515                                ret_rate = 0xff;
4516                                RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT);
4517                                break;
4518                }
4519        }
4520
4521        return ret_rate;
4522}
4523
4524/**
4525 * Function:     UpdateRxPktTimeStamp
4526 * Overview:     Recored down the TSF time stamp when receiving a packet
4527 *
4528 * Input:
4529 *       PADAPTER        Adapter
4530 *       PRT_RFD         pRfd,
4531 *
4532 * Output:
4533 *       PRT_RFD         pRfd
4534 *                               (pRfd->Status.TimeStampHigh is updated)
4535 *                               (pRfd->Status.TimeStampLow is updated)
4536 * Return:
4537 *               None
4538 */
4539void UpdateRxPktTimeStamp8190 (struct net_device *dev, struct ieee80211_rx_stats *stats)
4540{
4541        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
4542
4543        if(stats->bIsAMPDU && !stats->bFirstMPDU) {
4544                stats->mac_time[0] = priv->LastRxDescTSFLow;
4545                stats->mac_time[1] = priv->LastRxDescTSFHigh;
4546        } else {
4547                priv->LastRxDescTSFLow = stats->mac_time[0];
4548                priv->LastRxDescTSFHigh = stats->mac_time[1];
4549        }
4550}
4551
4552//by amy 080606
4553
4554long rtl819x_translate_todbm(u8 signal_strength_index   )// 0-100 index.
4555{
4556        long    signal_power; // in dBm.
4557
4558        // Translate to dBm (x=0.5y-95).
4559        signal_power = (long)((signal_strength_index + 1) >> 1);
4560        signal_power -= 95;
4561
4562        return signal_power;
4563}
4564
4565
4566/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to
4567    be a local static. Otherwise, it may increase when we return from S3/S4. The
4568    value will be kept in memory or disk. We must delcare the value in adapter
4569    and it will be reinitialized when return from S3/S4. */
4570void rtl8192_process_phyinfo(struct r8192_priv * priv,u8* buffer, struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats)
4571{
4572        bool bcheck = false;
4573        u8      rfpath;
4574        u32     nspatial_stream, tmp_val;
4575        //u8    i;
4576        static u32 slide_rssi_index=0, slide_rssi_statistics=0;
4577        static u32 slide_evm_index=0, slide_evm_statistics=0;
4578        static u32 last_rssi=0, last_evm=0;
4579
4580        static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0;
4581        static u32 last_beacon_adc_pwdb=0;
4582
4583        struct ieee80211_hdr_3addr *hdr;
4584        u16 sc ;
4585        unsigned int frag,seq;
4586        hdr = (struct ieee80211_hdr_3addr *)buffer;
4587        sc = le16_to_cpu(hdr->seq_ctl);
4588        frag = WLAN_GET_SEQ_FRAG(sc);
4589        seq = WLAN_GET_SEQ_SEQ(sc);
4590        //cosa add 04292008 to record the sequence number
4591        pcurrent_stats->Seq_Num = seq;
4592        //
4593        // Check whether we should take the previous packet into accounting
4594        //
4595        if(!pprevious_stats->bIsAMPDU)
4596        {
4597                // if previous packet is not aggregated packet
4598                bcheck = true;
4599        }else
4600        {
4601        }
4602
4603
4604        if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX)
4605        {
4606                slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX;
4607                last_rssi = priv->stats.slide_signal_strength[slide_rssi_index];
4608                priv->stats.slide_rssi_total -= last_rssi;
4609        }
4610        priv->stats.slide_rssi_total += pprevious_stats->SignalStrength;
4611
4612        priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength;
4613        if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX)
4614                slide_rssi_index = 0;
4615
4616        // <1> Showed on UI for user, in dbm
4617        tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics;
4618        priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val);
4619        pcurrent_stats->rssi = priv->stats.signal_strength;
4620        //
4621        // If the previous packet does not match the criteria, neglect it
4622        //
4623        if(!pprevious_stats->bPacketMatchBSSID)
4624        {
4625                if(!pprevious_stats->bToSelfBA)
4626                        return;
4627        }
4628
4629        if(!bcheck)
4630                return;
4631
4632
4633        //rtl8190_process_cck_rxpathsel(priv,pprevious_stats);//only rtl8190 supported
4634
4635        //
4636        // Check RSSI
4637        //
4638        priv->stats.num_process_phyinfo++;
4639
4640        /* record the general signal strength to the sliding window. */
4641
4642
4643        // <2> Showed on UI for engineering
4644        // hardware does not provide rssi information for each rf path in CCK
4645        if(!pprevious_stats->bIsCCK && (pprevious_stats->bPacketToSelf || pprevious_stats->bToSelfBA))
4646        {
4647                for (rfpath = RF90_PATH_A; rfpath < priv->NumTotalRFPath; rfpath++)
4648                {
4649                     if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, rfpath))
4650                                 continue;
4651
4652                        //Fixed by Jacken 2008-03-20
4653                        if(priv->stats.rx_rssi_percentage[rfpath] == 0)
4654                        {
4655                                priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath];
4656                                //DbgPrint("MIMO RSSI initialize \n");
4657                        }
4658                        if(pprevious_stats->RxMIMOSignalStrength[rfpath]  > priv->stats.rx_rssi_percentage[rfpath])
4659                        {
4660                                priv->stats.rx_rssi_percentage[rfpath] =
4661                                        ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4662                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4663                                priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath]  + 1;
4664                        }
4665                        else
4666                        {
4667                                priv->stats.rx_rssi_percentage[rfpath] =
4668                                        ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) +
4669                                        (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor);
4670                        }
4671                        RT_TRACE(COMP_DBG,"priv->stats.rx_rssi_percentage[rfPath]  = %d \n" ,priv->stats.rx_rssi_percentage[rfpath] );
4672                }
4673        }
4674
4675
4676        //
4677        // Check PWDB.
4678        //
4679        RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4680                                pprevious_stats->bIsCCK? "CCK": "OFDM",
4681                                pprevious_stats->RxPWDBAll);
4682
4683        if(pprevious_stats->bPacketBeacon)
4684        {
4685/* record the beacon pwdb to the sliding window. */
4686                if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4687                {
4688                        slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX;
4689                        last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index];
4690                        priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb;
4691                        //DbgPrint("slide_beacon_adc_pwdb_index = %d, last_beacon_adc_pwdb = %d, Adapter->RxStats.Slide_Beacon_Total = %d\n",
4692                        //      slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total);
4693                }
4694                priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll;
4695                priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll;
4696                //DbgPrint("slide_beacon_adc_pwdb_index = %d, pPreviousRfd->Status.RxPWDBAll = %d\n", slide_beacon_adc_pwdb_index, pPreviousRfd->Status.RxPWDBAll);
4697                slide_beacon_adc_pwdb_index++;
4698                if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX)
4699                        slide_beacon_adc_pwdb_index = 0;
4700                pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics;
4701                if(pprevious_stats->RxPWDBAll >= 3)
4702                        pprevious_stats->RxPWDBAll -= 3;
4703        }
4704
4705        RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n",
4706                                pprevious_stats->bIsCCK? "CCK": "OFDM",
4707                                pprevious_stats->RxPWDBAll);
4708
4709
4710        if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4711        {
4712                if(priv->undecorated_smoothed_pwdb < 0) // initialize
4713                {
4714                        priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll;
4715                        //DbgPrint("First pwdb initialize \n");
4716                }
4717                if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb)
4718                {
4719                        priv->undecorated_smoothed_pwdb =
4720                                        ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4721                                        (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4722                        priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1;
4723                }
4724                else
4725                {
4726                        priv->undecorated_smoothed_pwdb =
4727                                        ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) +
4728                                        (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor);
4729                }
4730
4731        }
4732
4733        //
4734        // Check EVM
4735        //
4736        /* record the general EVM to the sliding window. */
4737        if(pprevious_stats->SignalQuality == 0)
4738        {
4739        }
4740        else
4741        {
4742                if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){
4743                        if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){
4744                                slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX;
4745                                last_evm = priv->stats.slide_evm[slide_evm_index];
4746                                priv->stats.slide_evm_total -= last_evm;
4747                        }
4748
4749                        priv->stats.slide_evm_total += pprevious_stats->SignalQuality;
4750
4751                        priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality;
4752                        if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX)
4753                                slide_evm_index = 0;
4754
4755                        // <1> Showed on UI for user, in percentage.
4756                        tmp_val = priv->stats.slide_evm_total/slide_evm_statistics;
4757                        priv->stats.signal_quality = tmp_val;
4758                        //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality.
4759                        priv->stats.last_signal_strength_inpercent = tmp_val;
4760                }
4761
4762                // <2> Showed on UI for engineering
4763                if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA)
4764                {
4765                        for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream
4766                        {
4767                                if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1)
4768                                {
4769                                        if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize
4770                                        {
4771                                                priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream];
4772                                        }
4773                                        priv->stats.rx_evm_percentage[nspatial_stream] =
4774                                                ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) +
4775                                                (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor);
4776                                }
4777                        }
4778                }
4779        }
4780
4781
4782}
4783
4784/*-----------------------------------------------------------------------------
4785 * Function:    rtl819x_query_rxpwrpercentage()
4786 *
4787 * Overview:
4788 *
4789 * Input:               char            antpower
4790 *
4791 * Output:              NONE
4792 *
4793 * Return:              0-100 percentage
4794 *
4795 * Revised History:
4796 *      When            Who             Remark
4797 *      05/26/2008      amy             Create Version 0 porting from windows code.
4798 *
4799 *---------------------------------------------------------------------------*/
4800static u8 rtl819x_query_rxpwrpercentage(
4801        char            antpower
4802        )
4803{
4804        if ((antpower <= -100) || (antpower >= 20))
4805        {
4806                return  0;
4807        }
4808        else if (antpower >= 0)
4809        {
4810                return  100;
4811        }
4812        else
4813        {
4814                return  (100+antpower);
4815        }
4816
4817}       /* QueryRxPwrPercentage */
4818
4819static u8
4820rtl819x_evm_dbtopercentage(
4821    char value
4822    )
4823{
4824    char ret_val;
4825
4826    ret_val = value;
4827
4828    if(ret_val >= 0)
4829        ret_val = 0;
4830    if(ret_val <= -33)
4831        ret_val = -33;
4832    ret_val = 0 - ret_val;
4833    ret_val*=3;
4834        if(ret_val == 99)
4835                ret_val = 100;
4836    return(ret_val);
4837}
4838//
4839//      Description:
4840//      We want good-looking for signal strength/quality
4841//      2007/7/19 01:09, by cosa.
4842//
4843long
4844rtl819x_signal_scale_mapping(
4845        long currsig
4846        )
4847{
4848        long retsig;
4849
4850        // Step 1. Scale mapping.
4851        if(currsig >= 61 && currsig <= 100)
4852        {
4853                retsig = 90 + ((currsig - 60) / 4);
4854        }
4855        else if(currsig >= 41 && currsig <= 60)
4856        {
4857                retsig = 78 + ((currsig - 40) / 2);
4858        }
4859        else if(currsig >= 31 && currsig <= 40)
4860        {
4861                retsig = 66 + (currsig - 30);
4862        }
4863        else if(currsig >= 21 && currsig <= 30)
4864        {
4865                retsig = 54 + (currsig - 20);
4866        }
4867        else if(currsig >= 5 && currsig <= 20)
4868        {
4869                retsig = 42 + (((currsig - 5) * 2) / 3);
4870        }
4871        else if(currsig == 4)
4872        {
4873                retsig = 36;
4874        }
4875        else if(currsig == 3)
4876        {
4877                retsig = 27;
4878        }
4879        else if(currsig == 2)
4880        {
4881                retsig = 18;
4882        }
4883        else if(currsig == 1)
4884        {
4885                retsig = 9;
4886        }
4887        else
4888        {
4889                retsig = currsig;
4890        }
4891
4892        return retsig;
4893}
4894
4895static void rtl8192_query_rxphystatus(
4896        struct r8192_priv * priv,
4897        struct ieee80211_rx_stats * pstats,
4898        rx_drvinfo_819x_usb  * pdrvinfo,
4899        struct ieee80211_rx_stats * precord_stats,
4900        bool bpacket_match_bssid,
4901        bool bpacket_toself,
4902        bool bPacketBeacon,
4903        bool bToSelfBA
4904        )
4905{
4906        //PRT_RFD_STATUS                pRtRfdStatus = &(pRfd->Status);
4907        phy_sts_ofdm_819xusb_t* pofdm_buf;
4908        phy_sts_cck_819xusb_t   *       pcck_buf;
4909        phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc;
4910        u8                              *prxpkt;
4911        u8                              i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg;
4912        char                            rx_pwr[4], rx_pwr_all=0;
4913        //long                          rx_avg_pwr = 0;
4914        char                            rx_snrX, rx_evmX;
4915        u8                              evm, pwdb_all;
4916        u32                             RSSI, total_rssi=0;//, total_evm=0;
4917//      long                            signal_strength_index = 0;
4918        u8                              is_cck_rate=0;
4919        u8                              rf_rx_num = 0;
4920
4921
4922        priv->stats.numqry_phystatus++;
4923
4924        is_cck_rate = rx_hal_is_cck_rate(pdrvinfo);
4925
4926        // Record it for next packet processing
4927        memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats));
4928        pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid;
4929        pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself;
4930        pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo);
4931        pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon;
4932        pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA;
4933
4934        prxpkt = (u8*)pdrvinfo;
4935
4936        /* Move pointer to the 16th bytes. Phy status start address. */
4937        prxpkt += sizeof(rx_drvinfo_819x_usb);
4938
4939        /* Initial the cck and ofdm buffer pointer */
4940        pcck_buf = (phy_sts_cck_819xusb_t *)prxpkt;
4941        pofdm_buf = (phy_sts_ofdm_819xusb_t *)prxpkt;
4942
4943        pstats->RxMIMOSignalQuality[0] = -1;
4944        pstats->RxMIMOSignalQuality[1] = -1;
4945        precord_stats->RxMIMOSignalQuality[0] = -1;
4946        precord_stats->RxMIMOSignalQuality[1] = -1;
4947
4948        if(is_cck_rate)
4949        {
4950                //
4951                // (1)Hardware does not provide RSSI for CCK
4952                //
4953
4954                //
4955                // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
4956                //
4957                u8 report;//, cck_agc_rpt;
4958
4959                priv->stats.numqry_phystatusCCK++;
4960
4961                if(!priv->bCckHighPower)
4962                {
4963                        report = pcck_buf->cck_agc_rpt & 0xc0;
4964                        report = report>>6;
4965                        switch(report)
4966                        {
4967                                //Fixed by Jacken from Bryant 2008-03-20
4968                                //Original value is -38 , -26 , -14 , -2
4969                                //Fixed value is -35 , -23 , -11 , 6
4970                                case 0x3:
4971                                        rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e);
4972                                        break;
4973                                case 0x2:
4974                                        rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e);
4975                                        break;
4976                                case 0x1:
4977                                        rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e);
4978                                        break;
4979                                case 0x0:
4980                                        rx_pwr_all = 6 - (pcck_buf->cck_agc_rpt & 0x3e);
4981                                        break;
4982                        }
4983                }
4984                else
4985                {
4986                        report = pcck_buf->cck_agc_rpt & 0x60;
4987                        report = report>>5;
4988                        switch(report)
4989                        {
4990                                case 0x3:
4991                                        rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4992                                        break;
4993                                case 0x2:
4994                                        rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1);
4995                                        break;
4996                                case 0x1:
4997                                        rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
4998                                        break;
4999                                case 0x0:
5000                                        rx_pwr_all = 6 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ;
5001                                        break;
5002                        }
5003                }
5004
5005                pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5006                pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5007                pstats->RecvSignalPower = pwdb_all;
5008
5009                //
5010                // (3) Get Signal Quality (EVM)
5011                //
5012                //if(bpacket_match_bssid)
5013                {
5014                        u8      sq;
5015
5016                        if(pstats->RxPWDBAll > 40)
5017                        {
5018                                sq = 100;
5019                        }else
5020                        {
5021                                sq = pcck_buf->sq_rpt;
5022
5023                                if(pcck_buf->sq_rpt > 64)
5024                                        sq = 0;
5025                                else if (pcck_buf->sq_rpt < 20)
5026                                        sq = 100;
5027                                else
5028                                        sq = ((64-sq) * 100) / 44;
5029                        }
5030                        pstats->SignalQuality = precord_stats->SignalQuality = sq;
5031                        pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq;
5032                        pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1;
5033                }
5034        }
5035        else
5036        {
5037                priv->stats.numqry_phystatusHT++;
5038                //
5039                // (1)Get RSSI for HT rate
5040                //
5041                for(i=RF90_PATH_A; i<priv->NumTotalRFPath; i++)
5042                {
5043                        // 2008/01/30 MH we will judge RF RX path now.
5044                        if (priv->brfpath_rxenable[i])
5045                                rf_rx_num++;
5046                        else
5047                                continue;
5048
5049                if (!rtl8192_phy_CheckIsLegalRFPath(priv->ieee80211->dev, i))
5050                                continue;
5051
5052                        //Fixed by Jacken from Bryant 2008-03-20
5053                        //Original value is 106
5054                        rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 106;
5055
5056                        //Get Rx snr value in DB
5057                        tmp_rxsnr =     pofdm_buf->rxsnr_X[i];
5058                        rx_snrX = (char)(tmp_rxsnr);
5059                        //rx_snrX >>= 1;
5060                        rx_snrX /= 2;
5061                        priv->stats.rxSNRdB[i] = (long)rx_snrX;
5062
5063                        /* Translate DBM to percentage. */
5064                        RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]);
5065                        total_rssi += RSSI;
5066
5067                        /* Record Signal Strength for next packet */
5068                        //if(bpacket_match_bssid)
5069                        {
5070                                pstats->RxMIMOSignalStrength[i] =(u8) RSSI;
5071                                precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI;
5072                        }
5073                }
5074
5075
5076                //
5077                // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
5078                //
5079                //Fixed by Jacken from Bryant 2008-03-20
5080                //Original value is 106
5081                rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106;
5082                pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all);
5083
5084                pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all;
5085                pstats->RxPower = precord_stats->RxPower =  rx_pwr_all;
5086
5087                //
5088                // (3)EVM of HT rate
5089                //
5090                if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 &&
5091                        pdrvinfo->RxRate<=DESC90_RATEMCS15)
5092                        max_spatial_stream = 2; //both spatial stream make sense
5093                else
5094                        max_spatial_stream = 1; //only spatial stream 1 makes sense
5095
5096                for(i=0; i<max_spatial_stream; i++)
5097                {
5098                        tmp_rxevm =     pofdm_buf->rxevm_X[i];
5099                        rx_evmX = (char)(tmp_rxevm);
5100
5101                        // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
5102                        // fill most significant bit to "zero" when doing shifting operation which may change a negative
5103                        // value to positive one, then the dbm value (which is supposed to be negative)  is not correct anymore.
5104                        rx_evmX /= 2;   //dbm
5105
5106                        evm = rtl819x_evm_dbtopercentage(rx_evmX);
5107                        //if(bpacket_match_bssid)
5108                        {
5109                                if(i==0) // Fill value in RFD, Get the first spatial stream only
5110                                        pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff);
5111                                pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff);
5112                        }
5113                }
5114
5115
5116                /* record rx statistics for debug */
5117                rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg;
5118                prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg;
5119                if(pdrvinfo->BW)        //40M channel
5120                        priv->stats.received_bwtype[1+prxsc->rxsc]++;
5121                else                            //20M channel
5122                        priv->stats.received_bwtype[0]++;
5123        }
5124
5125        //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
5126        //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
5127        if(is_cck_rate)
5128        {
5129                pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL;
5130
5131        }
5132        else
5133        {
5134                //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u8)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u8)(total_rssi/=RF90_PATH_MAX);
5135                // We can judge RX path number now.
5136                if (rf_rx_num != 0)
5137                        pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num)));
5138        }
5139}       /* QueryRxPhyStatus8190Pci */
5140
5141void
5142rtl8192_record_rxdesc_forlateruse(
5143        struct ieee80211_rx_stats *     psrc_stats,
5144        struct ieee80211_rx_stats *     ptarget_stats
5145)
5146{
5147        ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU;
5148        ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU;
5149        ptarget_stats->Seq_Num = psrc_stats->Seq_Num;
5150}
5151
5152
5153void TranslateRxSignalStuff819xUsb(struct sk_buff *skb,
5154                                   struct ieee80211_rx_stats * pstats,
5155                                   rx_drvinfo_819x_usb  *pdrvinfo)
5156{
5157        // TODO: We must only check packet for current MAC address. Not finish
5158        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5159        struct net_device *dev=info->dev;
5160        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5161        bool bpacket_match_bssid, bpacket_toself;
5162        bool bPacketBeacon=FALSE, bToSelfBA=FALSE;
5163        static struct ieee80211_rx_stats  previous_stats;
5164        struct ieee80211_hdr_3addr *hdr;//by amy
5165       u16 fc,type;
5166
5167        // Get Signal Quality for only RX data queue (but not command queue)
5168
5169        u8* tmp_buf;
5170        //u16 tmp_buf_len = 0;
5171        u8  *praddr;
5172
5173        /* Get MAC frame start address. */
5174        tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);
5175
5176        hdr = (struct ieee80211_hdr_3addr *)tmp_buf;
5177        fc = le16_to_cpu(hdr->frame_ctl);
5178        type = WLAN_FC_GET_TYPE(fc);
5179        praddr = hdr->addr1;
5180
5181        /* Check if the received packet is acceptabe. */
5182        bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) &&
5183                                                        (eqMacAddr(priv->ieee80211->current_network.bssid,  (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
5184                                                                 && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV));
5185        bpacket_toself =  bpacket_match_bssid & (eqMacAddr(praddr, priv->ieee80211->dev->dev_addr));
5186
5187                if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON)
5188                {
5189                        bPacketBeacon = true;
5190                        //DbgPrint("Beacon 2, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5191                }
5192                if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK)
5193                {
5194                        if((eqMacAddr(praddr,dev->dev_addr)))
5195                                bToSelfBA = true;
5196                                //DbgPrint("BlockAck, MatchBSSID = %d, ToSelf = %d \n", bPacketMatchBSSID, bPacketToSelf);
5197                }
5198
5199
5200
5201        if(bpacket_match_bssid)
5202        {
5203                priv->stats.numpacket_matchbssid++;
5204        }
5205        if(bpacket_toself){
5206                priv->stats.numpacket_toself++;
5207        }
5208        //
5209        // Process PHY information for previous packet (RSSI/PWDB/EVM)
5210        //
5211        // Because phy information is contained in the last packet of AMPDU only, so driver
5212        // should process phy information of previous packet
5213        rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats);
5214        rtl8192_query_rxphystatus(priv, pstats, pdrvinfo, &previous_stats, bpacket_match_bssid,bpacket_toself,bPacketBeacon,bToSelfBA);
5215        rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats);
5216
5217}
5218
5219/**
5220* Function:     UpdateReceivedRateHistogramStatistics
5221* Overview:     Recored down the received data rate
5222*
5223* Input:
5224*       struct net_device *dev
5225*       struct ieee80211_rx_stats *stats
5226*
5227* Output:
5228*
5229*                       (priv->stats.ReceivedRateHistogram[] is updated)
5230* Return:
5231*               None
5232*/
5233void
5234UpdateReceivedRateHistogramStatistics8190(
5235        struct net_device *dev,
5236        struct ieee80211_rx_stats *stats
5237        )
5238{
5239        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5240        u32 rcvType=1;   //0: Total, 1:OK, 2:CRC, 3:ICV
5241        u32 rateIndex;
5242        u32 preamble_guardinterval;  //1: short preamble/GI, 0: long preamble/GI
5243
5244
5245        if(stats->bCRC)
5246        rcvType = 2;
5247        else if(stats->bICV)
5248        rcvType = 3;
5249
5250        if(stats->bShortPreamble)
5251        preamble_guardinterval = 1;// short
5252        else
5253        preamble_guardinterval = 0;// long
5254
5255        switch(stats->rate)
5256        {
5257                //
5258                // CCK rate
5259                //
5260                case MGN_1M:    rateIndex = 0;  break;
5261                case MGN_2M:    rateIndex = 1;  break;
5262                case MGN_5_5M:  rateIndex = 2;  break;
5263                case MGN_11M:   rateIndex = 3;  break;
5264                //
5265                // Legacy OFDM rate
5266                //
5267                case MGN_6M:    rateIndex = 4;  break;
5268                case MGN_9M:    rateIndex = 5;  break;
5269                case MGN_12M:   rateIndex = 6;  break;
5270                case MGN_18M:   rateIndex = 7;  break;
5271                case MGN_24M:   rateIndex = 8;  break;
5272                case MGN_36M:   rateIndex = 9;  break;
5273                case MGN_48M:   rateIndex = 10; break;
5274                case MGN_54M:   rateIndex = 11; break;
5275                //
5276                // 11n High throughput rate
5277                //
5278                case MGN_MCS0:  rateIndex = 12; break;
5279                case MGN_MCS1:  rateIndex = 13; break;
5280                case MGN_MCS2:  rateIndex = 14; break;
5281                case MGN_MCS3:  rateIndex = 15; break;
5282                case MGN_MCS4:  rateIndex = 16; break;
5283                case MGN_MCS5:  rateIndex = 17; break;
5284                case MGN_MCS6:  rateIndex = 18; break;
5285                case MGN_MCS7:  rateIndex = 19; break;
5286                case MGN_MCS8:  rateIndex = 20; break;
5287                case MGN_MCS9:  rateIndex = 21; break;
5288                case MGN_MCS10: rateIndex = 22; break;
5289                case MGN_MCS11: rateIndex = 23; break;
5290                case MGN_MCS12: rateIndex = 24; break;
5291                case MGN_MCS13: rateIndex = 25; break;
5292                case MGN_MCS14: rateIndex = 26; break;
5293                case MGN_MCS15: rateIndex = 27; break;
5294                default:        rateIndex = 28; break;
5295        }
5296    priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++;
5297    priv->stats.received_rate_histogram[0][rateIndex]++; //total
5298    priv->stats.received_rate_histogram[rcvType][rateIndex]++;
5299}
5300
5301
5302void query_rxdesc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats, bool bIsRxAggrSubframe)
5303{
5304        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5305        struct net_device *dev=info->dev;
5306        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5307        //rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5308        rx_drvinfo_819x_usb  *driver_info = NULL;
5309
5310        //
5311        //Get Rx Descriptor Information
5312        //
5313#ifdef USB_RX_AGGREGATION_SUPPORT
5314        if (bIsRxAggrSubframe)
5315        {
5316                rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data;
5317                stats->Length = desc->Length ;
5318                stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5319                stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact.
5320                stats->bICV = desc->ICV;
5321                stats->bCRC = desc->CRC32;
5322                stats->bHwError = stats->bCRC|stats->bICV;
5323                stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet
5324        } else
5325#endif
5326        {
5327                rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5328
5329                stats->Length = desc->Length;
5330                stats->RxDrvInfoSize = desc->RxDrvInfoSize;
5331                stats->RxBufShift = 0;//desc->Shift&0x03;
5332                stats->bICV = desc->ICV;
5333                stats->bCRC = desc->CRC32;
5334                stats->bHwError = stats->bCRC|stats->bICV;
5335                //RTL8190 set this bit to indicate that Hw does not decrypt packet
5336                stats->Decrypted = !desc->SWDec;
5337        }
5338
5339        if((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP))
5340        {
5341                stats->bHwError = false;
5342        }
5343        else
5344        {
5345                stats->bHwError = stats->bCRC|stats->bICV;
5346        }
5347
5348        if(stats->Length < 24 || stats->Length > MAX_8192U_RX_SIZE)
5349                stats->bHwError |= 1;
5350        //
5351        //Get Driver Info
5352        //
5353        // TODO: Need to verify it on FGPA platform
5354        //Driver info are written to the RxBuffer following rx desc
5355        if (stats->RxDrvInfoSize != 0) {
5356                driver_info = (rx_drvinfo_819x_usb *)(skb->data + sizeof(rx_desc_819x_usb) + \
5357                                stats->RxBufShift);
5358                /* unit: 0.5M */
5359                /* TODO */
5360                if(!stats->bHwError){
5361                        u8      ret_rate;
5362                        ret_rate = HwRateToMRate90(driver_info->RxHT, driver_info->RxRate);
5363                        if(ret_rate == 0xff)
5364                        {
5365                                // Abnormal Case: Receive CRC OK packet with Rx descriptor indicating non supported rate.
5366                                // Special Error Handling here, 2008.05.16, by Emily
5367
5368                                stats->bHwError = 1;
5369                                stats->rate = MGN_1M;   //Set 1M rate by default
5370                        }else
5371                        {
5372                                stats->rate = ret_rate;
5373                        }
5374                }
5375                else
5376                        stats->rate = 0x02;
5377
5378                stats->bShortPreamble = driver_info->SPLCP;
5379
5380
5381                UpdateReceivedRateHistogramStatistics8190(dev, stats);
5382
5383                stats->bIsAMPDU = (driver_info->PartAggr==1);
5384                stats->bFirstMPDU = (driver_info->PartAggr==1) && (driver_info->FirstAGGR==1);
5385                stats->TimeStampLow = driver_info->TSFL;
5386                // xiong mask it, 070514
5387                //pRfd->Status.TimeStampHigh = PlatformEFIORead4Byte(Adapter, TSFR+4);
5388                // stats->TimeStampHigh = read_nic_dword(dev,  TSFR+4);
5389
5390                UpdateRxPktTimeStamp8190(dev, stats);
5391
5392                //
5393                // Rx A-MPDU
5394                //
5395                if(driver_info->FirstAGGR==1 || driver_info->PartAggr == 1)
5396                        RT_TRACE(COMP_RXDESC, "driver_info->FirstAGGR = %d, driver_info->PartAggr = %d\n",
5397                                        driver_info->FirstAGGR, driver_info->PartAggr);
5398
5399        }
5400
5401        skb_pull(skb,sizeof(rx_desc_819x_usb));
5402        //
5403        // Get Total offset of MPDU Frame Body
5404        //
5405        if((stats->RxBufShift + stats->RxDrvInfoSize) > 0) {
5406                stats->bShift = 1;
5407                skb_pull(skb,stats->RxBufShift + stats->RxDrvInfoSize);
5408        }
5409
5410#ifdef USB_RX_AGGREGATION_SUPPORT
5411        /* for the rx aggregated sub frame, the redundant space truelly contained in the packet */
5412        if(bIsRxAggrSubframe) {
5413                skb_pull(skb, 8);
5414        }
5415#endif
5416        /* for debug 2008.5.29 */
5417
5418        //added by vivi, for MP, 20080108
5419        stats->RxIs40MHzPacket = driver_info->BW;
5420        if(stats->RxDrvInfoSize != 0)
5421                TranslateRxSignalStuff819xUsb(skb, stats, driver_info);
5422
5423}
5424
5425u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats  *Status, bool bIsRxAggrSubframe)
5426{
5427#ifdef USB_RX_AGGREGATION_SUPPORT
5428        if (bIsRxAggrSubframe)
5429                return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5430                        + Status->RxBufShift + 8);
5431        else
5432#endif
5433                return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize
5434                                + Status->RxBufShift);
5435}
5436
5437void rtl8192_rx_nomal(struct sk_buff* skb)
5438{
5439        rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5440        struct net_device *dev=info->dev;
5441        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5442        struct ieee80211_rx_stats stats = {
5443                .signal = 0,
5444                .noise = -98,
5445                .rate = 0,
5446                //      .mac_time = jiffies,
5447                .freq = IEEE80211_24GHZ_BAND,
5448        };
5449        u32 rx_pkt_len = 0;
5450        struct ieee80211_hdr_1addr *ieee80211_hdr = NULL;
5451        bool unicast_packet = false;
5452#ifdef USB_RX_AGGREGATION_SUPPORT
5453        struct sk_buff *agg_skb = NULL;
5454        u32  TotalLength = 0;
5455        u32  TempDWord = 0;
5456        u32  PacketLength = 0;
5457        u32  PacketOccupiedLendth = 0;
5458        u8   TempByte = 0;
5459        u32  PacketShiftBytes = 0;
5460        rx_desc_819x_usb_aggr_subframe *RxDescr = NULL;
5461        u8  PaddingBytes = 0;
5462        //add just for testing
5463        u8   testing;
5464
5465#endif
5466
5467        /* 20 is for ps-poll */
5468        if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) {
5469#ifdef USB_RX_AGGREGATION_SUPPORT
5470                TempByte = *(skb->data + sizeof(rx_desc_819x_usb));
5471#endif
5472                /* first packet should not contain Rx aggregation header */
5473                query_rxdesc_status(skb, &stats, false);
5474                /* TODO */
5475                /* hardware related info */
5476#ifdef USB_RX_AGGREGATION_SUPPORT
5477                if (TempByte & BIT0) {
5478                        agg_skb = skb;
5479                        //TotalLength = agg_skb->len - 4; /*sCrcLng*/
5480                        TotalLength = stats.Length - 4; /*sCrcLng*/
5481                        //RT_TRACE(COMP_RECV, "%s:first aggregated packet!Length=%d\n",__FUNCTION__,TotalLength);
5482                        /* though the head pointer has passed this position  */
5483                        TempDWord = *(u32 *)(agg_skb->data - 4);
5484                        PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/
5485                        skb = dev_alloc_skb(PacketLength);
5486                        memcpy(skb_put(skb,PacketLength),agg_skb->data,PacketLength);
5487                        PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false);
5488                }
5489#endif
5490                /* Process the MPDU recevied */
5491                skb_trim(skb, skb->len - 4/*sCrcLng*/);
5492
5493                rx_pkt_len = skb->len;
5494                ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5495                unicast_packet = false;
5496                if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5497                        //TODO
5498                }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5499                        //TODO
5500                }else {
5501                        /* unicast packet */
5502                        unicast_packet = true;
5503                }
5504
5505                if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5506                        dev_kfree_skb_any(skb);
5507                } else {
5508                        priv->stats.rxoktotal++;
5509                        if(unicast_packet) {
5510                                priv->stats.rxbytesunicast += rx_pkt_len;
5511                        }
5512                }
5513#ifdef USB_RX_AGGREGATION_SUPPORT
5514                testing = 1;
5515                // (PipeIndex == 0) && (TempByte & BIT0) => TotalLength > 0.
5516                if (TotalLength > 0) {
5517                        PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8);
5518                        if ((PacketOccupiedLendth & 0xFF) != 0)
5519                                PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256;
5520                        PacketOccupiedLendth -= 8;
5521                        TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */
5522                        if (agg_skb->len > TempDWord)
5523                                skb_pull(agg_skb, TempDWord);
5524                        else
5525                                agg_skb->len = 0;
5526
5527                        while (agg_skb->len>=GetRxPacketShiftBytes819xUsb(&stats, true)) {
5528                                u8 tmpCRC = 0, tmpICV = 0;
5529                                //RT_TRACE(COMP_RECV,"%s:aggred pkt,total_len = %d\n",__FUNCTION__,agg_skb->len);
5530                                RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data);
5531                                tmpCRC = RxDescr->CRC32;
5532                                tmpICV = RxDescr->ICV;
5533                                memcpy(agg_skb->data, &agg_skb->data[44], 2);
5534                                RxDescr->CRC32 = tmpCRC;
5535                                RxDescr->ICV = tmpICV;
5536
5537                                memset(&stats, 0, sizeof(struct ieee80211_rx_stats));
5538                                stats.signal = 0;
5539                                stats.noise = -98;
5540                                stats.rate = 0;
5541                                stats.freq = IEEE80211_24GHZ_BAND;
5542                                query_rxdesc_status(agg_skb, &stats, true);
5543                                PacketLength = stats.Length;
5544
5545                                if(PacketLength > agg_skb->len) {
5546                                        break;
5547                                }
5548                                /* Process the MPDU recevied */
5549                                skb = dev_alloc_skb(PacketLength);
5550                                memcpy(skb_put(skb,PacketLength),agg_skb->data, PacketLength);
5551                                skb_trim(skb, skb->len - 4/*sCrcLng*/);
5552
5553                                rx_pkt_len = skb->len;
5554                                ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data;
5555                                unicast_packet = false;
5556                                if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) {
5557                                        //TODO
5558                                }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){
5559                                        //TODO
5560                                }else {
5561                                        /* unicast packet */
5562                                        unicast_packet = true;
5563                                }
5564                                if(!ieee80211_rx(priv->ieee80211,skb, &stats)) {
5565                                        dev_kfree_skb_any(skb);
5566                                } else {
5567                                        priv->stats.rxoktotal++;
5568                                        if(unicast_packet) {
5569                                                priv->stats.rxbytesunicast += rx_pkt_len;
5570                                        }
5571                                }
5572                                /* should trim the packet which has been copied to target skb */
5573                                skb_pull(agg_skb, PacketLength);
5574                                PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true);
5575                                PacketOccupiedLendth = PacketLength + PacketShiftBytes;
5576                                if ((PacketOccupiedLendth & 0xFF) != 0) {
5577                                        PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF);
5578                                        if (agg_skb->len > PaddingBytes)
5579                                                skb_pull(agg_skb, PaddingBytes);
5580                                        else
5581                                                agg_skb->len = 0;
5582                                }
5583                        }
5584                        dev_kfree_skb(agg_skb);
5585                }
5586#endif
5587        } else {
5588                priv->stats.rxurberr++;
5589                printk("actual_length:%d\n", skb->len);
5590                dev_kfree_skb_any(skb);
5591        }
5592
5593}
5594
5595void
5596rtl819xusb_process_received_packet(
5597        struct net_device *dev,
5598        struct ieee80211_rx_stats *pstats
5599        )
5600{
5601//      bool bfreerfd=false, bqueued=false;
5602        u8*     frame;
5603        u16     frame_len=0;
5604        struct r8192_priv *priv = ieee80211_priv(dev);
5605//      u8                      index = 0;
5606//      u8                      TID = 0;
5607        //u16                   seqnum = 0;
5608        //PRX_TS_RECORD pts = NULL;
5609
5610        // Get shifted bytes of Starting address of 802.11 header. 2006.09.28, by Emily
5611        //porting by amy 080508
5612        pstats->virtual_address += get_rxpacket_shiftbytes_819xusb(pstats);
5613        frame = pstats->virtual_address;
5614        frame_len = pstats->packetlength;
5615#ifdef TODO     // by amy about HCT
5616        if(!Adapter->bInHctTest)
5617                CountRxErrStatistics(Adapter, pRfd);
5618#endif
5619        {
5620        #ifdef ENABLE_PS  //by amy for adding ps function in future
5621                RT_RF_POWER_STATE rtState;
5622                // When RF is off, we should not count the packet for hw/sw synchronize
5623                // reason, ie. there may be a duration while sw switch is changed and hw
5624                // switch is being changed. 2006.12.04, by shien chang.
5625                Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RF_STATE, (u8* )(&rtState));
5626                if (rtState == eRfOff)
5627                {
5628                        return;
5629                }
5630        #endif
5631        priv->stats.rxframgment++;
5632
5633        }
5634#ifdef TODO
5635        RmMonitorSignalStrength(Adapter, pRfd);
5636#endif
5637        /* 2007/01/16 MH Add RX command packet handle here. */
5638        /* 2007/03/01 MH We have to release RFD and return if rx pkt is cmd pkt. */
5639        if (rtl819xusb_rx_command_packet(dev, pstats))
5640        {
5641                return;
5642        }
5643
5644#ifdef SW_CRC_CHECK
5645        SwCrcCheck();
5646#endif
5647
5648
5649}
5650
5651void query_rx_cmdpkt_desc_status(struct sk_buff *skb, struct ieee80211_rx_stats *stats)
5652{
5653//      rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5654//      struct net_device *dev=info->dev;
5655//      struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5656        rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data;
5657//      rx_drvinfo_819x_usb  *driver_info;
5658
5659        //
5660        //Get Rx Descriptor Information
5661        //
5662        stats->virtual_address = (u8*)skb->data;
5663        stats->Length = desc->Length;
5664        stats->RxDrvInfoSize = 0;
5665        stats->RxBufShift = 0;
5666        stats->packetlength = stats->Length-scrclng;
5667        stats->fraglength = stats->packetlength;
5668        stats->fragoffset = 0;
5669        stats->ntotalfrag = 1;
5670}
5671
5672
5673void rtl8192_rx_cmd(struct sk_buff *skb)
5674{
5675        struct rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb;
5676        struct net_device *dev = info->dev;
5677        //int ret;
5678//      struct urb *rx_urb = info->urb;
5679        /* TODO */
5680        struct ieee80211_rx_stats stats = {
5681                .signal = 0,
5682                .noise = -98,
5683                .rate = 0,
5684                //      .mac_time = jiffies,
5685                .freq = IEEE80211_24GHZ_BAND,
5686        };
5687
5688        if((skb->len >=(20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE))
5689        {
5690
5691                query_rx_cmdpkt_desc_status(skb,&stats);
5692                // this is to be done by amy 080508     prfd->queue_id = 1;
5693
5694
5695                //
5696                //  Process the command packet received.
5697                //
5698
5699                rtl819xusb_process_received_packet(dev,&stats);
5700
5701                dev_kfree_skb_any(skb);
5702        }
5703        else
5704                ;
5705
5706
5707}
5708
5709void rtl8192_irq_rx_tasklet(struct r8192_priv *priv)
5710{
5711        struct sk_buff *skb;
5712        struct rtl8192_rx_info *info;
5713
5714        while (NULL != (skb = skb_dequeue(&priv->skb_queue))) {
5715                info = (struct rtl8192_rx_info *)skb->cb;
5716                switch (info->out_pipe) {
5717                /* Nomal packet pipe */
5718                        case 3:
5719                                //RT_TRACE(COMP_RECV, "normal in-pipe index(%d)\n",info->out_pipe);
5720                                priv->IrpPendingCount--;
5721                                rtl8192_rx_nomal(skb);
5722                                break;
5723
5724                                /* Command packet pipe */
5725                        case 9:
5726                                RT_TRACE(COMP_RECV, "command in-pipe index(%d)\n",\
5727                                                info->out_pipe);
5728
5729                                rtl8192_rx_cmd(skb);
5730                                break;
5731
5732                        default: /* should never get here! */
5733                                RT_TRACE(COMP_ERR, "Unknown in-pipe index(%d)\n",\
5734                                                info->out_pipe);
5735                                dev_kfree_skb(skb);
5736                                break;
5737
5738                }
5739        }
5740}
5741
5742static const struct net_device_ops rtl8192_netdev_ops = {
5743        .ndo_open               = rtl8192_open,
5744        .ndo_stop               = rtl8192_close,
5745        .ndo_get_stats          = rtl8192_stats,
5746        .ndo_tx_timeout         = tx_timeout,
5747        .ndo_do_ioctl           = rtl8192_ioctl,
5748        .ndo_set_multicast_list = r8192_set_multicast,
5749        .ndo_set_mac_address    = r8192_set_mac_adr,
5750        .ndo_validate_addr      = eth_validate_addr,
5751        .ndo_change_mtu         = eth_change_mtu,
5752        .ndo_start_xmit         = ieee80211_xmit,
5753};
5754
5755
5756/****************************************************************************
5757     ---------------------------- USB_STUFF---------------------------
5758*****************************************************************************/
5759
5760static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
5761                         const struct usb_device_id *id)
5762{
5763//      unsigned long ioaddr = 0;
5764        struct net_device *dev = NULL;
5765        struct r8192_priv *priv= NULL;
5766        struct usb_device *udev = interface_to_usbdev(intf);
5767        int ret;
5768        RT_TRACE(COMP_INIT, "Oops: i'm coming\n");
5769
5770        dev = alloc_ieee80211(sizeof(struct r8192_priv));
5771        if (dev == NULL)
5772                return -ENOMEM;
5773
5774        usb_set_intfdata(intf, dev);
5775        SET_NETDEV_DEV(dev, &intf->dev);
5776        priv = ieee80211_priv(dev);
5777        priv->ieee80211 = netdev_priv(dev);
5778        priv->udev=udev;
5779
5780        dev->netdev_ops = &rtl8192_netdev_ops;
5781
5782         //DMESG("Oops: i'm coming\n");
5783#if WIRELESS_EXT >= 12
5784#if WIRELESS_EXT < 17
5785        dev->get_wireless_stats = r8192_get_wireless_stats;
5786#endif
5787        dev->wireless_handlers = (struct iw_handler_def *) &r8192_wx_handlers_def;
5788#endif
5789        dev->type=ARPHRD_ETHER;
5790
5791        dev->watchdog_timeo = HZ*3;     //modified by john, 0805
5792
5793        if (dev_alloc_name(dev, ifname) < 0){
5794                RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n");
5795                ifname = "wlan%d";
5796                dev_alloc_name(dev, ifname);
5797        }
5798
5799        RT_TRACE(COMP_INIT, "Driver probe completed1\n");
5800        if(rtl8192_init(dev)!=0){
5801                RT_TRACE(COMP_ERR, "Initialization failed");
5802                ret = -ENODEV;
5803                goto fail;
5804        }
5805        netif_carrier_off(dev);
5806        netif_stop_queue(dev);
5807
5808        ret = register_netdev(dev);
5809        if (ret)
5810                goto fail2;
5811
5812        RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name);
5813        rtl8192_proc_init_one(dev);
5814
5815
5816        RT_TRACE(COMP_INIT, "Driver probe completed\n");
5817        return 0;
5818
5819fail2:
5820        rtl8192_down(dev);
5821        kfree(priv->pFirmware);
5822        priv->pFirmware = NULL;
5823        rtl8192_usb_deleteendpoints(dev);
5824        destroy_workqueue(priv->priv_wq);
5825        mdelay(10);
5826fail:
5827        free_ieee80211(dev);
5828
5829        RT_TRACE(COMP_ERR, "wlan driver load failed\n");
5830        return ret;
5831}
5832
5833//detach all the work and timer structure declared or inititialize in r8192U_init function.
5834void rtl8192_cancel_deferred_work(struct r8192_priv* priv)
5835{
5836
5837        cancel_work_sync(&priv->reset_wq);
5838        cancel_delayed_work(&priv->watch_dog_wq);
5839        cancel_delayed_work(&priv->update_beacon_wq);
5840        cancel_work_sync(&priv->qos_activate);
5841        //cancel_work_sync(&priv->SetBWModeWorkItem);
5842        //cancel_work_sync(&priv->SwChnlWorkItem);
5843
5844}
5845
5846
5847static void __devexit rtl8192_usb_disconnect(struct usb_interface *intf)
5848{
5849        struct net_device *dev = usb_get_intfdata(intf);
5850
5851        struct r8192_priv *priv = ieee80211_priv(dev);
5852        if(dev){
5853
5854                unregister_netdev(dev);
5855
5856                RT_TRACE(COMP_DOWN, "=============>wlan driver to be removed\n");
5857                rtl8192_proc_remove_one(dev);
5858
5859                        rtl8192_down(dev);
5860                kfree(priv->pFirmware);
5861                priv->pFirmware = NULL;
5862        //      priv->rf_close(dev);
5863//              rtl8192_SetRFPowerState(dev, eRfOff);
5864                rtl8192_usb_deleteendpoints(dev);
5865                destroy_workqueue(priv->priv_wq);
5866                //rtl8192_irq_disable(dev);
5867                //rtl8192_reset(dev);
5868                mdelay(10);
5869
5870        }
5871        free_ieee80211(dev);
5872        RT_TRACE(COMP_DOWN, "wlan driver removed\n");
5873}
5874
5875/* fun with the built-in ieee80211 stack... */
5876extern int ieee80211_debug_init(void);
5877extern void ieee80211_debug_exit(void);
5878extern int ieee80211_crypto_init(void);
5879extern void ieee80211_crypto_deinit(void);
5880extern int ieee80211_crypto_tkip_init(void);
5881extern void ieee80211_crypto_tkip_exit(void);
5882extern int ieee80211_crypto_ccmp_init(void);
5883extern void ieee80211_crypto_ccmp_exit(void);
5884extern int ieee80211_crypto_wep_init(void);
5885extern void ieee80211_crypto_wep_exit(void);
5886
5887static int __init rtl8192_usb_module_init(void)
5888{
5889        int ret;
5890
5891#ifdef CONFIG_IEEE80211_DEBUG
5892        ret = ieee80211_debug_init();
5893        if (ret) {
5894                printk(KERN_ERR "ieee80211_debug_init() failed %d\n", ret);
5895                return ret;
5896        }
5897#endif
5898        ret = ieee80211_crypto_init();
5899        if (ret) {
5900                printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
5901                return ret;
5902        }
5903
5904        ret = ieee80211_crypto_tkip_init();
5905        if (ret) {
5906                printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n",
5907                        ret);
5908                return ret;
5909        }
5910
5911        ret = ieee80211_crypto_ccmp_init();
5912        if (ret) {
5913                printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n",
5914                        ret);
5915                return ret;
5916        }
5917
5918        ret = ieee80211_crypto_wep_init();
5919        if (ret) {
5920                printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
5921                return ret;
5922        }
5923
5924        printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n");
5925        printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n");
5926        RT_TRACE(COMP_INIT, "Initializing module");
5927        RT_TRACE(COMP_INIT, "Wireless extensions version %d", WIRELESS_EXT);
5928        rtl8192_proc_module_init();
5929        return usb_register(&rtl8192_usb_driver);
5930}
5931
5932
5933static void __exit rtl8192_usb_module_exit(void)
5934{
5935        usb_deregister(&rtl8192_usb_driver);
5936
5937        RT_TRACE(COMP_DOWN, "Exiting");
5938//      rtl8192_proc_module_remove();
5939}
5940
5941
5942void rtl8192_try_wake_queue(struct net_device *dev, int pri)
5943{
5944        unsigned long flags;
5945        short enough_desc;
5946        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5947
5948        spin_lock_irqsave(&priv->tx_lock,flags);
5949        enough_desc = check_nic_enough_desc(dev,pri);
5950        spin_unlock_irqrestore(&priv->tx_lock,flags);
5951
5952        if(enough_desc)
5953                ieee80211_wake_queue(priv->ieee80211);
5954}
5955
5956void EnableHWSecurityConfig8192(struct net_device *dev)
5957{
5958        u8 SECR_value = 0x0;
5959        struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev);
5960         struct ieee80211_device* ieee = priv->ieee80211;
5961        SECR_value = SCR_TxEncEnable | SCR_RxDecEnable;
5962        if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2))
5963        {
5964                SECR_value |= SCR_RxUseDK;
5965                SECR_value |= SCR_TxUseDK;
5966        }
5967        else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP)))
5968        {
5969                SECR_value |= SCR_RxUseDK;
5970                SECR_value |= SCR_TxUseDK;
5971        }
5972        //add HWSec active enable here.
5973//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
5974
5975        ieee->hwsec_active = 1;
5976
5977        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
5978        {
5979                ieee->hwsec_active = 0;
5980                SECR_value &= ~SCR_RxDecEnable;
5981        }
5982        RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, \
5983                        ieee->hwsec_active, ieee->pairwise_key_type, SECR_value);
5984        {
5985                write_nic_byte(dev, SECR,  SECR_value);//SECR_value |  SCR_UseDK );
5986        }
5987}
5988
5989
5990void setKey(    struct net_device *dev,
5991                u8 EntryNo,
5992                u8 KeyIndex,
5993                u16 KeyType,
5994                u8 *MacAddr,
5995                u8 DefaultKey,
5996                u32 *KeyContent )
5997{
5998        u32 TargetCommand = 0;
5999        u32 TargetContent = 0;
6000        u16 usConfig = 0;
6001        u8 i;
6002        if (EntryNo >= TOTAL_CAM_ENTRY)
6003                RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n");
6004
6005        RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", dev,EntryNo, KeyIndex, KeyType, MacAddr);
6006
6007        if (DefaultKey)
6008                usConfig |= BIT15 | (KeyType<<2);
6009        else
6010                usConfig |= BIT15 | (KeyType<<2) | KeyIndex;
6011//      usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex;
6012
6013
6014        for(i=0 ; i<CAM_CONTENT_COUNT; i++){
6015                TargetCommand  = i+CAM_CONTENT_COUNT*EntryNo;
6016                TargetCommand |= BIT31|BIT16;
6017
6018                if(i==0){//MAC|Config
6019                        TargetContent = (u32)(*(MacAddr+0)) << 16|
6020                                        (u32)(*(MacAddr+1)) << 24|
6021                                        (u32)usConfig;
6022
6023                        write_nic_dword(dev, WCAMI, TargetContent);
6024                        write_nic_dword(dev, RWCAM, TargetCommand);
6025        //              printk("setkey cam =%8x\n", read_cam(dev, i+6*EntryNo));
6026                }
6027                else if(i==1){//MAC
6028                        TargetContent = (u32)(*(MacAddr+2))      |
6029                                        (u32)(*(MacAddr+3)) <<  8|
6030                                        (u32)(*(MacAddr+4)) << 16|
6031                                        (u32)(*(MacAddr+5)) << 24;
6032                        write_nic_dword(dev, WCAMI, TargetContent);
6033                        write_nic_dword(dev, RWCAM, TargetCommand);
6034                }
6035                else {
6036                        //Key Material
6037                        if(KeyContent !=NULL){
6038                        write_nic_dword(dev, WCAMI, (u32)(*(KeyContent+i-2)) );
6039                        write_nic_dword(dev, RWCAM, TargetCommand);
6040                }
6041        }
6042        }
6043
6044}
6045
6046/***************************************************************************
6047     ------------------- module init / exit stubs ----------------
6048****************************************************************************/
6049module_init(rtl8192_usb_module_init);
6050module_exit(rtl8192_usb_module_exit);
6051