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