linux/drivers/staging/rtl8192e/r819xE_cmdpkt.c
<<
>>
Prefs
   1/******************************************************************************
   2
   3     (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
   4
   5 Module:        r819xusb_cmdpkt.c       (RTL8190 TX/RX command packet handler Source C File)
   6
   7 Note:      The module is responsible for handling TX and RX command packet.
   8                        1. TX : Send set and query configuration command packet.
   9                        2. RX : Receive tx feedback, beacon state, query configuration
  10                                command packet.
  11
  12 Function:
  13
  14 Export:
  15
  16 Abbrev:
  17
  18 History:
  19        Data            Who             Remark
  20
  21        05/06/2008  amy         Create initial version porting from windows driver.
  22
  23******************************************************************************/
  24#include "r8192E.h"
  25#include "r8192E_hw.h"
  26#include "r819xE_cmdpkt.h"
  27
  28/*
  29 * Driver internal module can call the API to send message to
  30 * firmware side. For example, you can send a debug command packet.
  31 * Or you can send a request for FW to modify RLX4181 LBUS HW bank.
  32 * Otherwise, you can change MAC/PHT/RF register by firmware at
  33 * run time. We do not support message more than one segment now.
  34 */
  35RT_STATUS cmpk_message_handle_tx(
  36        struct net_device *dev,
  37        u8*     code_virtual_address,
  38        u32     packettype,
  39        u32     buffer_len)
  40{
  41
  42        RT_STATUS           rt_status = RT_STATUS_SUCCESS;
  43#ifdef RTL8192U
  44        return rt_status;
  45#else
  46        struct r8192_priv   *priv = ieee80211_priv(dev);
  47        u16                 frag_threshold;
  48        u16                 frag_length = 0, frag_offset = 0;
  49        rt_firmware         *pfirmware = priv->pFirmware;
  50        struct sk_buff      *skb;
  51        unsigned char       *seg_ptr;
  52        cb_desc             *tcb_desc;
  53        u8                  bLastIniPkt;
  54
  55        PTX_FWINFO_8190PCI      pTxFwInfo = NULL;
  56        int i;
  57
  58        //spin_lock_irqsave(&priv->tx_lock,flags);
  59        RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
  60        firmware_init_param(dev);
  61        //Fragmentation might be required
  62        frag_threshold = pfirmware->cmdpacket_frag_thresold;
  63        do {
  64            if((buffer_len - frag_offset) > frag_threshold) {
  65                frag_length = frag_threshold ;
  66                bLastIniPkt = 0;
  67
  68            } else {
  69                frag_length =(u16)(buffer_len - frag_offset);
  70                bLastIniPkt = 1;
  71
  72            }
  73
  74            /* Allocate skb buffer to contain firmware info and tx descriptor info
  75             * add 4 to avoid packet appending overflow.
  76             * */
  77#ifdef RTL8192U
  78            skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
  79#else
  80            skb  = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4);
  81#endif
  82            if(skb == NULL) {
  83                rt_status = RT_STATUS_FAILURE;
  84                goto Failed;
  85            }
  86
  87            memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
  88            tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
  89            tcb_desc->queue_index = TXCMD_QUEUE;
  90            tcb_desc->bCmdOrInit = packettype;
  91            tcb_desc->bLastIniPkt = bLastIniPkt;
  92            tcb_desc->pkt_size = frag_length;
  93
  94#ifdef RTL8192U
  95            skb_reserve(skb, USB_HWDESC_HEADER_LEN);
  96#endif
  97
  98            //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom);
  99            seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom);
 100
 101            pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
 102            memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
 103            memset(pTxFwInfo,0x12,8);
 104
 105            seg_ptr +=sizeof(TX_FWINFO_8190PCI);
 106
 107            /*
 108             * Transform from little endian to big endian
 109             * and pending  zero
 110             */
 111            seg_ptr = skb_tail_pointer(skb);
 112            for(i=0 ; i < frag_length; i+=4) {
 113                *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
 114                *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
 115                *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
 116                *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
 117            }
 118            skb_put(skb, i);
 119            priv->ieee80211->softmac_hard_start_xmit(skb,dev);
 120
 121            code_virtual_address += frag_length;
 122            frag_offset += frag_length;
 123
 124        }while(frag_offset < buffer_len);
 125
 126Failed:
 127        //spin_unlock_irqrestore(&priv->tx_lock,flags);
 128        return rt_status;
 129
 130
 131#endif
 132}
 133
 134static void
 135cmpk_count_txstatistic(
 136        struct net_device *dev,
 137        cmpk_txfb_t     *pstx_fb)
 138{
 139        struct r8192_priv *priv = ieee80211_priv(dev);
 140#ifdef ENABLE_PS
 141        RT_RF_POWER_STATE       rtState;
 142
 143        pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
 144
 145        // When RF is off, we should not count the packet for hw/sw synchronize
 146        // reason, ie. there may be a duration while sw switch is changed and hw
 147        // switch is being changed. 2006.12.04, by shien chang.
 148        if (rtState == eRfOff)
 149        {
 150                return;
 151        }
 152#endif
 153
 154#ifdef TODO
 155        if(pAdapter->bInHctTest)
 156                return;
 157#endif
 158        /* We can not know the packet length and transmit type: broadcast or uni
 159           or multicast. So the relative statistics must be collected in tx
 160           feedback info. */
 161        if (pstx_fb->tok)
 162        {
 163                priv->stats.txfeedbackok++;
 164                priv->stats.txoktotal++;
 165                priv->stats.txokbytestotal += pstx_fb->pkt_length;
 166                priv->stats.txokinperiod++;
 167
 168                /* We can not make sure broadcast/multicast or unicast mode. */
 169                if (pstx_fb->pkt_type == PACKET_MULTICAST)
 170                {
 171                        priv->stats.txmulticast++;
 172                        priv->stats.txbytesmulticast += pstx_fb->pkt_length;
 173                }
 174                else if (pstx_fb->pkt_type == PACKET_BROADCAST)
 175                {
 176                        priv->stats.txbroadcast++;
 177                        priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
 178                }
 179                else
 180                {
 181                        priv->stats.txunicast++;
 182                        priv->stats.txbytesunicast += pstx_fb->pkt_length;
 183                }
 184        }
 185        else
 186        {
 187                priv->stats.txfeedbackfail++;
 188                priv->stats.txerrtotal++;
 189                priv->stats.txerrbytestotal += pstx_fb->pkt_length;
 190
 191                /* We can not make sure broadcast/multicast or unicast mode. */
 192                if (pstx_fb->pkt_type == PACKET_MULTICAST)
 193                {
 194                        priv->stats.txerrmulticast++;
 195                }
 196                else if (pstx_fb->pkt_type == PACKET_BROADCAST)
 197                {
 198                        priv->stats.txerrbroadcast++;
 199                }
 200                else
 201                {
 202                        priv->stats.txerrunicast++;
 203                }
 204        }
 205
 206        priv->stats.txretrycount += pstx_fb->retry_cnt;
 207        priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
 208
 209}
 210
 211
 212
 213/*
 214 * The function is responsible for extract the message inside TX
 215 * feedbck message from firmware. It will contain dedicated info in
 216 * ws-06-0063-rtl8190-command-packet-specification. Please
 217 * refer to chapter "TX Feedback Element". We have to read 20 bytes
 218 * in the command packet.
 219 */
 220static void
 221cmpk_handle_tx_feedback(
 222        struct net_device *dev,
 223        u8      *       pmsg)
 224{
 225        struct r8192_priv *priv = ieee80211_priv(dev);
 226        cmpk_txfb_t             rx_tx_fb;       /* */
 227
 228        priv->stats.txfeedback++;
 229
 230        /* 0. Display received message. */
 231        //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
 232
 233        /* 1. Extract TX feedback info from RFD to temp structure buffer. */
 234        /* It seems that FW use big endian(MIPS) and DRV use little endian in
 235           windows OS. So we have to read the content byte by byte or transfer
 236           endian type before copy the message copy. */
 237#if 0           // The TX FEEDBACK packet element address
 238        //rx_tx_fb.Element_ID   = pMsg[0];
 239        //rx_tx_fb.Length               = pMsg[1];
 240        rx_tx_fb.TOK                    = pMsg[2]>>7;
 241        rx_tx_fb.Fail_Reason    = (pMsg[2] & 0x70) >> 4;
 242        rx_tx_fb.TID                    = (pMsg[2] & 0x0F);
 243        rx_tx_fb.Qos_Pkt                = pMsg[3] >> 7;
 244        rx_tx_fb.Bandwidth              = (pMsg[3] & 0x40) >> 6;
 245        rx_tx_fb.Retry_Cnt              = pMsg[5];
 246        rx_tx_fb.Pkt_ID                 = (pMsg[6] << 8) | pMsg[7];
 247        rx_tx_fb.Seq_Num                = (pMsg[8] << 8) | pMsg[9];
 248        rx_tx_fb.S_Rate                 = pMsg[10];
 249        rx_tx_fb.F_Rate                 = pMsg[11];
 250        rx_tx_fb.S_RTS_Rate     = pMsg[12];
 251        rx_tx_fb.F_RTS_Rate     = pMsg[13];
 252        rx_tx_fb.pkt_length     = (pMsg[14] << 8) | pMsg[15];
 253#endif
 254        /* 2007/07/05 MH Use pointer to transfer structure memory. */
 255        //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
 256        memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
 257        /* 2. Use tx feedback info to count TX statistics. */
 258        cmpk_count_txstatistic(dev, &rx_tx_fb);
 259#if 0
 260        /* 2007/07/11 MH Assign current operate rate.  */
 261        if (pAdapter->RegWirelessMode == WIRELESS_MODE_A ||
 262                pAdapter->RegWirelessMode == WIRELESS_MODE_B ||
 263                pAdapter->RegWirelessMode == WIRELESS_MODE_G)
 264        {
 265                pMgntInfo->CurrentOperaRate = (rx_tx_fb.F_Rate & 0x7F);
 266        }
 267        else if (pAdapter->RegWirelessMode == WIRELESS_MODE_N_24G ||
 268                         pAdapter->RegWirelessMode == WIRELESS_MODE_N_5G)
 269        {
 270                pMgntInfo->HTCurrentOperaRate = (rx_tx_fb.F_Rate & 0x8F);
 271        }
 272#endif
 273        /* 2007/01/17 MH Comment previous method for TX statistic function. */
 274        /* Collect info TX feedback packet to fill TCB. */
 275        /* We can not know the packet length and transmit type: broadcast or uni
 276           or multicast. */
 277        //CountTxStatistics( pAdapter, &tcb );
 278
 279}
 280
 281
 282/*
 283 * The function is responsible for extract the message from
 284 * firmware. It will contain dedicated info in
 285 * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
 286 * Please refer to chapter "Interrupt Status Element".
 287 */
 288static  void
 289cmpk_handle_interrupt_status(
 290        struct net_device *dev,
 291        u8*     pmsg)
 292{
 293        cmpk_intr_sta_t         rx_intr_status; /* */
 294        struct r8192_priv *priv = ieee80211_priv(dev);
 295
 296        DMESG("---> cmpk_Handle_Interrupt_Status()\n");
 297
 298        /* 0. Display received message. */
 299        //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
 300
 301        /* 1. Extract TX feedback info from RFD to temp structure buffer. */
 302        /* It seems that FW use big endian(MIPS) and DRV use little endian in
 303           windows OS. So we have to read the content byte by byte or transfer
 304           endian type before copy the message copy. */
 305        //rx_bcn_state.Element_ID       = pMsg[0];
 306        //rx_bcn_state.Length           = pMsg[1];
 307        rx_intr_status.length = pmsg[1];
 308        if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
 309        {
 310                DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
 311                return;
 312        }
 313
 314
 315        // Statistics of beacon for ad-hoc mode.
 316        if(     priv->ieee80211->iw_mode == IW_MODE_ADHOC)
 317        {
 318                //2 maybe need endian transform?
 319                rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
 320                //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4)));
 321
 322                DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
 323
 324                if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
 325                {
 326                        priv->ieee80211->bibsscoordinator = true;
 327                        priv->stats.txbeaconokint++;
 328                }
 329                else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
 330                {
 331                        priv->ieee80211->bibsscoordinator = false;
 332                        priv->stats.txbeaconerr++;
 333                }
 334        }
 335
 336         // Other informations in interrupt status we need?
 337
 338
 339        DMESG("<---- cmpk_handle_interrupt_status()\n");
 340
 341}
 342
 343
 344/*
 345 * The function is responsible for extract the message from
 346 * firmware. It will contain dedicated info in
 347 * ws-06-0063-rtl8190-command-packet-specification. Please
 348 * refer to chapter "Beacon State Element".
 349 */
 350static  void
 351cmpk_handle_query_config_rx(
 352        struct net_device *dev,
 353        u8*        pmsg)
 354{
 355        cmpk_query_cfg_t        rx_query_cfg;   /* */
 356
 357        /* 0. Display received message. */
 358        //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
 359
 360        /* 1. Extract TX feedback info from RFD to temp structure buffer. */
 361        /* It seems that FW use big endian(MIPS) and DRV use little endian in
 362           windows OS. So we have to read the content byte by byte or transfer
 363           endian type before copy the message copy. */
 364        //rx_query_cfg.Element_ID       = pMsg[0];
 365        //rx_query_cfg.Length           = pMsg[1];
 366        rx_query_cfg.cfg_action         = (pmsg[4] & 0x80000000)>>31;
 367        rx_query_cfg.cfg_type           = (pmsg[4] & 0x60) >> 5;
 368        rx_query_cfg.cfg_size           = (pmsg[4] & 0x18) >> 3;
 369        rx_query_cfg.cfg_page           = (pmsg[6] & 0x0F) >> 0;
 370        rx_query_cfg.cfg_offset                 = pmsg[7];
 371        rx_query_cfg.value                      = (pmsg[8] << 24) | (pmsg[9] << 16) |
 372                                                                  (pmsg[10] << 8) | (pmsg[11] << 0);
 373        rx_query_cfg.mask                       = (pmsg[12] << 24) | (pmsg[13] << 16) |
 374                                                                  (pmsg[14] << 8) | (pmsg[15] << 0);
 375
 376}
 377
 378
 379/*
 380 * Count aggregated tx status from firmwar of one type rx command
 381 * packet element id = RX_TX_STATUS.
 382 */
 383static  void    cmpk_count_tx_status(   struct net_device *dev,
 384                                                                        cmpk_tx_status_t        *pstx_status)
 385{
 386        struct r8192_priv *priv = ieee80211_priv(dev);
 387
 388#ifdef ENABLE_PS
 389
 390        RT_RF_POWER_STATE       rtstate;
 391
 392        pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
 393
 394        // When RF is off, we should not count the packet for hw/sw synchronize
 395        // reason, ie. there may be a duration while sw switch is changed and hw
 396        // switch is being changed. 2006.12.04, by shien chang.
 397        if (rtState == eRfOff)
 398        {
 399                return;
 400        }
 401#endif
 402
 403        priv->stats.txfeedbackok        += pstx_status->txok;
 404        priv->stats.txoktotal           += pstx_status->txok;
 405
 406        priv->stats.txfeedbackfail      += pstx_status->txfail;
 407        priv->stats.txerrtotal          += pstx_status->txfail;
 408
 409        priv->stats.txretrycount                += pstx_status->txretry;
 410        priv->stats.txfeedbackretry     += pstx_status->txretry;
 411
 412        //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length;
 413        //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length;
 414        //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++;
 415
 416        priv->stats.txmulticast += pstx_status->txmcok;
 417        priv->stats.txbroadcast += pstx_status->txbcok;
 418        priv->stats.txunicast           += pstx_status->txucok;
 419
 420        priv->stats.txerrmulticast      += pstx_status->txmcfail;
 421        priv->stats.txerrbroadcast      += pstx_status->txbcfail;
 422        priv->stats.txerrunicast        += pstx_status->txucfail;
 423
 424        priv->stats.txbytesmulticast    += pstx_status->txmclength;
 425        priv->stats.txbytesbroadcast    += pstx_status->txbclength;
 426        priv->stats.txbytesunicast              += pstx_status->txuclength;
 427
 428        priv->stats.last_packet_rate            = pstx_status->rate;
 429}
 430
 431
 432
 433/*
 434 * Firmware add a new tx feedback status to reduce rx command
 435 * packet buffer operation load.
 436 */
 437static  void
 438cmpk_handle_tx_status(
 439        struct net_device *dev,
 440        u8*        pmsg)
 441{
 442        cmpk_tx_status_t        rx_tx_sts;      /* */
 443
 444        memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
 445        /* 2. Use tx feedback info to count TX statistics. */
 446        cmpk_count_tx_status(dev, &rx_tx_sts);
 447
 448}
 449
 450
 451/* Firmware add a new tx rate history */
 452static  void
 453cmpk_handle_tx_rate_history(
 454        struct net_device *dev,
 455        u8*        pmsg)
 456{
 457        cmpk_tx_rahis_t *ptxrate;
 458//      RT_RF_POWER_STATE       rtState;
 459        u8                              i, j;
 460        u16                             length = sizeof(cmpk_tx_rahis_t);
 461        u32                             *ptemp;
 462        struct r8192_priv *priv = ieee80211_priv(dev);
 463
 464
 465#ifdef ENABLE_PS
 466        pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
 467
 468        // When RF is off, we should not count the packet for hw/sw synchronize
 469        // reason, ie. there may be a duration while sw switch is changed and hw
 470        // switch is being changed. 2006.12.04, by shien chang.
 471        if (rtState == eRfOff)
 472        {
 473                return;
 474        }
 475#endif
 476
 477        ptemp = (u32 *)pmsg;
 478
 479        //
 480        // Do endian transfer to word alignment(16 bits) for windows system.
 481        // You must do different endian transfer for linux and MAC OS
 482        //
 483        for (i = 0; i < (length/4); i++)
 484        {
 485                u16      temp1, temp2;
 486
 487                temp1 = ptemp[i]&0x0000FFFF;
 488                temp2 = ptemp[i]>>16;
 489                ptemp[i] = (temp1<<16)|temp2;
 490        }
 491
 492        ptxrate = (cmpk_tx_rahis_t *)pmsg;
 493
 494        if (ptxrate == NULL )
 495        {
 496                return;
 497        }
 498
 499        for (i = 0; i < 16; i++)
 500        {
 501                // Collect CCK rate packet num
 502                if (i < 4)
 503                        priv->stats.txrate.cck[i] += ptxrate->cck[i];
 504
 505                // Collect OFDM rate packet num
 506                if (i< 8)
 507                        priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
 508
 509                for (j = 0; j < 4; j++)
 510                        priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
 511        }
 512
 513}
 514
 515
 516/*
 517 * In the function, we will capture different RX command packet
 518 * info. Every RX command packet element has different message
 519 * length and meaning in content. We only support three type of RX
 520 * command packet now. Please refer to document
 521 * ws-06-0063-rtl8190-command-packet-specification.
 522 */
 523u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats)
 524{
 525//      u32                     debug_level = DBG_LOUD;
 526        struct r8192_priv *priv = ieee80211_priv(dev);
 527        int                     total_length;
 528        u8                      cmd_length, exe_cnt = 0;
 529        u8                      element_id;
 530        u8                      *pcmd_buff;
 531
 532        RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx()\n");
 533
 534        /* 0. Check inpt arguments. If is is a command queue message or pointer is
 535              null. */
 536        if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
 537        {
 538                /* Print error message. */
 539                /*RT_TRACE(COMP_SEND, DebugLevel,
 540                                ("\n\r[CMPK]-->Err queue id or pointer"));*/
 541                return 0;       /* This is not a command packet. */
 542        }
 543
 544        /* 1. Read received command packet message length from RFD. */
 545        total_length = pstats->Length;
 546
 547        /* 2. Read virtual address from RFD. */
 548        pcmd_buff = pstats->virtual_address;
 549
 550        /* 3. Read command pakcet element id and length. */
 551        element_id = pcmd_buff[0];
 552        /*RT_TRACE(COMP_SEND, DebugLevel,
 553                        ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/
 554
 555        /* 4. Check every received command packet conent according to different
 556              element type. Because FW may aggregate RX command packet to minimize
 557              transmit time between DRV and FW.*/
 558        // Add a counter to prevent to locked in the loop too long
 559        while (total_length > 0 || exe_cnt++ >100)
 560        {
 561                /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */
 562                element_id = pcmd_buff[0];
 563
 564                switch(element_id)
 565                {
 566                        case RX_TX_FEEDBACK:
 567
 568                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
 569                                cmpk_handle_tx_feedback (dev, pcmd_buff);
 570                                cmd_length = CMPK_RX_TX_FB_SIZE;
 571                                break;
 572
 573                        case RX_INTERRUPT_STATUS:
 574
 575                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
 576                                cmpk_handle_interrupt_status(dev, pcmd_buff);
 577                                cmd_length = sizeof(cmpk_intr_sta_t);
 578                                break;
 579
 580                        case BOTH_QUERY_CONFIG:
 581
 582                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
 583                                cmpk_handle_query_config_rx(dev, pcmd_buff);
 584                                cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
 585                                break;
 586
 587                        case RX_TX_STATUS:
 588
 589                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
 590                                cmpk_handle_tx_status(dev, pcmd_buff);
 591                                cmd_length = CMPK_RX_TX_STS_SIZE;
 592                                break;
 593
 594                        case RX_TX_PER_PKT_FEEDBACK:
 595                                // You must at lease add a switch case element here,
 596                                // Otherwise, we will jump to default case.
 597                                //DbgPrint("CCX Test\r\n");
 598                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
 599                                cmd_length = CMPK_RX_TX_FB_SIZE;
 600                                break;
 601
 602                        case RX_TX_RATE_HISTORY:
 603                                //DbgPrint(" rx tx rate history\r\n");
 604
 605                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
 606                                cmpk_handle_tx_rate_history(dev, pcmd_buff);
 607                                cmd_length = CMPK_TX_RAHIS_SIZE;
 608                                break;
 609
 610                        default:
 611
 612                                RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknown CMD Element\n");
 613                                return 1;       /* This is a command packet. */
 614                }
 615                // 2007/01/22 MH Display received rx command packet info.
 616                //cmpk_Display_Message(cmd_length, pcmd_buff);
 617
 618                // 2007/01/22 MH Add to display tx statistic.
 619                //cmpk_DisplayTxStatistic(pAdapter);
 620
 621                /* 2007/03/09 MH Collect sidderent cmd element pkt num. */
 622                priv->stats.rxcmdpkt[element_id]++;
 623
 624                total_length -= cmd_length;
 625                pcmd_buff    += cmd_length;
 626        }       /* while (total_length > 0) */
 627        return  1;      /* This is a command packet. */
 628
 629        RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
 630}
 631