Staging: rtl8192u: remove dead code
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rtl8192u / r819xU_cmdpkt.c
blobfd19a85297a9052ab070b1d395be7b24650e8b7d
1 /******************************************************************************
3 (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved.
5 Module: r819xusb_cmdpkt.c (RTL8190 TX/RX command packet handler Source C File)
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.
12 Function:
14 Export:
16 Abbrev:
18 History:
19 Data Who Remark
21 05/06/2008 amy Create initial version porting from windows driver.
23 ******************************************************************************/
24 #include "r8192U.h"
25 #include "r819xU_cmdpkt.h"
26 /*---------------------------Define Local Constant---------------------------*/
27 /* Debug constant*/
28 #define CMPK_DEBOUNCE_CNT 1
29 /* 2007/10/24 MH Add for printing a range of data. */
30 #define CMPK_PRINT(Address)\
32 unsigned char i;\
33 u32 temp[10];\
35 memcpy(temp, Address, 40);\
36 for (i = 0; i <40; i+=4)\
37 printk("\r\n %08x", temp[i]);\
39 /*---------------------------Define functions---------------------------------*/
41 rt_status
42 SendTxCommandPacket(
43 struct net_device *dev,
44 void* pData,
45 u32 DataLen
48 rt_status rtStatus = RT_STATUS_SUCCESS;
49 struct r8192_priv *priv = ieee80211_priv(dev);
50 struct sk_buff *skb;
51 cb_desc *tcb_desc;
52 unsigned char *ptr_buf;
53 //bool bLastInitPacket = false;
55 //PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
57 //Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ)
58 skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4);
59 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
60 tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
61 tcb_desc->queue_index = TXCMD_QUEUE;
62 tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
63 tcb_desc->bLastIniPkt = 0;
64 skb_reserve(skb, USB_HWDESC_HEADER_LEN);
65 ptr_buf = skb_put(skb, DataLen);
66 memset(ptr_buf,0,DataLen);
67 memcpy(ptr_buf,pData,DataLen);
68 tcb_desc->txbuf_size= (u16)DataLen;
70 if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
71 (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
72 (priv->ieee80211->queue_stop) ) {
73 RT_TRACE(COMP_FIRMWARE,"===================NULL packet==================================> tx full!\n");
74 skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
75 } else {
76 priv->ieee80211->softmac_hard_start_xmit(skb,dev);
79 //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
80 return rtStatus;
83 /*-----------------------------------------------------------------------------
84 * Function: cmpk_message_handle_tx()
86 * Overview: Driver internal module can call the API to send message to
87 * firmware side. For example, you can send a debug command packet.
88 * Or you can send a request for FW to modify RLX4181 LBUS HW bank.
89 * Otherwise, you can change MAC/PHT/RF register by firmware at
90 * run time. We do not support message more than one segment now.
92 * Input: NONE
94 * Output: NONE
96 * Return: NONE
98 * Revised History:
99 * When Who Remark
100 * 05/06/2008 amy porting from windows code.
102 *---------------------------------------------------------------------------*/
103 extern rt_status cmpk_message_handle_tx(
104 struct net_device *dev,
105 u8* codevirtualaddress,
106 u32 packettype,
107 u32 buffer_len)
110 bool rt_status = true;
111 #ifdef RTL8192U
112 return rt_status;
113 #else
114 struct r8192_priv *priv = ieee80211_priv(dev);
115 u16 frag_threshold;
116 u16 frag_length, frag_offset = 0;
117 //u16 total_size;
118 //int i;
120 rt_firmware *pfirmware = priv->pFirmware;
121 struct sk_buff *skb;
122 unsigned char *seg_ptr;
123 cb_desc *tcb_desc;
124 u8 bLastIniPkt;
126 firmware_init_param(dev);
127 //Fragmentation might be required
128 frag_threshold = pfirmware->cmdpacket_frag_thresold;
129 do {
130 if((buffer_len - frag_offset) > frag_threshold) {
131 frag_length = frag_threshold ;
132 bLastIniPkt = 0;
134 } else {
135 frag_length = buffer_len - frag_offset;
136 bLastIniPkt = 1;
140 /* Allocate skb buffer to contain firmware info and tx descriptor info
141 * add 4 to avoid packet appending overflow.
142 * */
143 #ifdef RTL8192U
144 skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
145 #else
146 skb = dev_alloc_skb(frag_length + 4);
147 #endif
148 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
149 tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
150 tcb_desc->queue_index = TXCMD_QUEUE;
151 tcb_desc->bCmdOrInit = packettype;
152 tcb_desc->bLastIniPkt = bLastIniPkt;
154 #ifdef RTL8192U
155 skb_reserve(skb, USB_HWDESC_HEADER_LEN);
156 #endif
158 seg_ptr = skb_put(skb, buffer_len);
160 * Transform from little endian to big endian
161 * and pending zero
163 memcpy(seg_ptr,codevirtualaddress,buffer_len);
164 tcb_desc->txbuf_size= (u16)buffer_len;
167 if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
168 (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
169 (priv->ieee80211->queue_stop) ) {
170 RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
171 skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
172 } else {
173 priv->ieee80211->softmac_hard_start_xmit(skb,dev);
176 codevirtualaddress += frag_length;
177 frag_offset += frag_length;
179 }while(frag_offset < buffer_len);
181 return rt_status;
184 #endif
185 } /* CMPK_Message_Handle_Tx */
187 /*-----------------------------------------------------------------------------
188 * Function: cmpk_counttxstatistic()
190 * Overview:
192 * Input: PADAPTER pAdapter - .
193 * CMPK_TXFB_T *psTx_FB - .
195 * Output: NONE
197 * Return: NONE
199 * Revised History:
200 * When Who Remark
201 * 05/12/2008 amy Create Version 0 porting from windows code.
203 *---------------------------------------------------------------------------*/
204 static void
205 cmpk_count_txstatistic(
206 struct net_device *dev,
207 cmpk_txfb_t *pstx_fb)
209 struct r8192_priv *priv = ieee80211_priv(dev);
210 #ifdef ENABLE_PS
211 RT_RF_POWER_STATE rtState;
213 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
215 // When RF is off, we should not count the packet for hw/sw synchronize
216 // reason, ie. there may be a duration while sw switch is changed and hw
217 // switch is being changed. 2006.12.04, by shien chang.
218 if (rtState == eRfOff)
220 return;
222 #endif
224 #ifdef TODO
225 if(pAdapter->bInHctTest)
226 return;
227 #endif
228 /* We can not know the packet length and transmit type: broadcast or uni
229 or multicast. So the relative statistics must be collected in tx
230 feedback info. */
231 if (pstx_fb->tok)
233 priv->stats.txfeedbackok++;
234 priv->stats.txoktotal++;
235 priv->stats.txokbytestotal += pstx_fb->pkt_length;
236 priv->stats.txokinperiod++;
238 /* We can not make sure broadcast/multicast or unicast mode. */
239 if (pstx_fb->pkt_type == PACKET_MULTICAST)
241 priv->stats.txmulticast++;
242 priv->stats.txbytesmulticast += pstx_fb->pkt_length;
244 else if (pstx_fb->pkt_type == PACKET_BROADCAST)
246 priv->stats.txbroadcast++;
247 priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
249 else
251 priv->stats.txunicast++;
252 priv->stats.txbytesunicast += pstx_fb->pkt_length;
255 else
257 priv->stats.txfeedbackfail++;
258 priv->stats.txerrtotal++;
259 priv->stats.txerrbytestotal += pstx_fb->pkt_length;
261 /* We can not make sure broadcast/multicast or unicast mode. */
262 if (pstx_fb->pkt_type == PACKET_MULTICAST)
264 priv->stats.txerrmulticast++;
266 else if (pstx_fb->pkt_type == PACKET_BROADCAST)
268 priv->stats.txerrbroadcast++;
270 else
272 priv->stats.txerrunicast++;
276 priv->stats.txretrycount += pstx_fb->retry_cnt;
277 priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
279 } /* cmpk_CountTxStatistic */
283 /*-----------------------------------------------------------------------------
284 * Function: cmpk_handle_tx_feedback()
286 * Overview: The function is responsible for extract the message inside TX
287 * feedbck message from firmware. It will contain dedicated info in
288 * ws-06-0063-rtl8190-command-packet-specification. Please
289 * refer to chapter "TX Feedback Element". We have to read 20 bytes
290 * in the command packet.
292 * Input: struct net_device * dev
293 * u8 * pmsg - Msg Ptr of the command packet.
295 * Output: NONE
297 * Return: NONE
299 * Revised History:
300 * When Who Remark
301 * 05/08/2008 amy Create Version 0 porting from windows code.
303 *---------------------------------------------------------------------------*/
304 static void
305 cmpk_handle_tx_feedback(
306 struct net_device *dev,
307 u8 * pmsg)
309 struct r8192_priv *priv = ieee80211_priv(dev);
310 cmpk_txfb_t rx_tx_fb; /* */
312 priv->stats.txfeedback++;
314 /* 0. Display received message. */
315 //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
317 /* 1. Extract TX feedback info from RFD to temp structure buffer. */
318 /* It seems that FW use big endian(MIPS) and DRV use little endian in
319 windows OS. So we have to read the content byte by byte or transfer
320 endian type before copy the message copy. */
321 /* 2007/07/05 MH Use pointer to transfer structure memory. */
322 //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
323 memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
324 /* 2. Use tx feedback info to count TX statistics. */
325 cmpk_count_txstatistic(dev, &rx_tx_fb);
326 /* 2007/01/17 MH Comment previous method for TX statistic function. */
327 /* Collect info TX feedback packet to fill TCB. */
328 /* We can not know the packet length and transmit type: broadcast or uni
329 or multicast. */
330 //CountTxStatistics( pAdapter, &tcb );
332 } /* cmpk_Handle_Tx_Feedback */
334 void
335 cmdpkt_beacontimerinterrupt_819xusb(
336 struct net_device *dev
339 struct r8192_priv *priv = ieee80211_priv(dev);
340 u16 tx_rate;
343 // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn.
345 if(priv->ieee80211->current_network.mode == IEEE_A ||
346 priv->ieee80211->current_network.mode == IEEE_N_5G ||
347 (priv->ieee80211->current_network.mode == IEEE_N_24G && (!priv->ieee80211->pHTInfo->bCurSuppCCK)))
349 tx_rate = 60;
350 DMESG("send beacon frame tx rate is 6Mbpm\n");
352 else
354 tx_rate =10;
355 DMESG("send beacon frame tx rate is 1Mbpm\n");
358 rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon
367 /*-----------------------------------------------------------------------------
368 * Function: cmpk_handle_interrupt_status()
370 * Overview: The function is responsible for extract the message from
371 * firmware. It will contain dedicated info in
372 * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
373 * Please refer to chapter "Interrupt Status Element".
375 * Input: struct net_device *dev,
376 * u8* pmsg - Message Pointer of the command packet.
378 * Output: NONE
380 * Return: NONE
382 * Revised History:
383 * When Who Remark
384 * 05/12/2008 amy Add this for rtl8192 porting from windows code.
386 *---------------------------------------------------------------------------*/
387 static void
388 cmpk_handle_interrupt_status(
389 struct net_device *dev,
390 u8* pmsg)
392 cmpk_intr_sta_t rx_intr_status; /* */
393 struct r8192_priv *priv = ieee80211_priv(dev);
395 DMESG("---> cmpk_Handle_Interrupt_Status()\n");
397 /* 0. Display received message. */
398 //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
400 /* 1. Extract TX feedback info from RFD to temp structure buffer. */
401 /* It seems that FW use big endian(MIPS) and DRV use little endian in
402 windows OS. So we have to read the content byte by byte or transfer
403 endian type before copy the message copy. */
404 //rx_bcn_state.Element_ID = pMsg[0];
405 //rx_bcn_state.Length = pMsg[1];
406 rx_intr_status.length = pmsg[1];
407 if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
409 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
410 return;
414 // Statistics of beacon for ad-hoc mode.
415 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC)
417 //2 maybe need endian transform?
418 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
419 //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4)));
421 DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
423 if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
425 priv->ieee80211->bibsscoordinator = true;
426 priv->stats.txbeaconokint++;
428 else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
430 priv->ieee80211->bibsscoordinator = false;
431 priv->stats.txbeaconerr++;
434 if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
436 cmdpkt_beacontimerinterrupt_819xusb(dev);
441 // Other informations in interrupt status we need?
444 DMESG("<---- cmpk_handle_interrupt_status()\n");
446 } /* cmpk_handle_interrupt_status */
449 /*-----------------------------------------------------------------------------
450 * Function: cmpk_handle_query_config_rx()
452 * Overview: The function is responsible for extract the message from
453 * firmware. It will contain dedicated info in
454 * ws-06-0063-rtl8190-command-packet-specification. Please
455 * refer to chapter "Beacon State Element".
457 * Input: u8 * pmsg - Message Pointer of the command packet.
459 * Output: NONE
461 * Return: NONE
463 * Revised History:
464 * When Who Remark
465 * 05/12/2008 amy Create Version 0 porting from windows code.
467 *---------------------------------------------------------------------------*/
468 static void
469 cmpk_handle_query_config_rx(
470 struct net_device *dev,
471 u8* pmsg)
473 cmpk_query_cfg_t rx_query_cfg; /* */
475 /* 0. Display received message. */
476 //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
478 /* 1. Extract TX feedback info from RFD to temp structure buffer. */
479 /* It seems that FW use big endian(MIPS) and DRV use little endian in
480 windows OS. So we have to read the content byte by byte or transfer
481 endian type before copy the message copy. */
482 //rx_query_cfg.Element_ID = pMsg[0];
483 //rx_query_cfg.Length = pMsg[1];
484 rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31;
485 rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5;
486 rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3;
487 rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0;
488 rx_query_cfg.cfg_offset = pmsg[7];
489 rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) |
490 (pmsg[10] << 8) | (pmsg[11] << 0);
491 rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
492 (pmsg[14] << 8) | (pmsg[15] << 0);
494 } /* cmpk_Handle_Query_Config_Rx */
497 /*-----------------------------------------------------------------------------
498 * Function: cmpk_count_tx_status()
500 * Overview: Count aggregated tx status from firmwar of one type rx command
501 * packet element id = RX_TX_STATUS.
503 * Input: NONE
505 * Output: NONE
507 * Return: NONE
509 * Revised History:
510 * When Who Remark
511 * 05/12/2008 amy Create Version 0 porting from windows code.
513 *---------------------------------------------------------------------------*/
514 static void cmpk_count_tx_status( struct net_device *dev,
515 cmpk_tx_status_t *pstx_status)
517 struct r8192_priv *priv = ieee80211_priv(dev);
519 #ifdef ENABLE_PS
521 RT_RF_POWER_STATE rtstate;
523 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
525 // When RF is off, we should not count the packet for hw/sw synchronize
526 // reason, ie. there may be a duration while sw switch is changed and hw
527 // switch is being changed. 2006.12.04, by shien chang.
528 if (rtState == eRfOff)
530 return;
532 #endif
534 priv->stats.txfeedbackok += pstx_status->txok;
535 priv->stats.txoktotal += pstx_status->txok;
537 priv->stats.txfeedbackfail += pstx_status->txfail;
538 priv->stats.txerrtotal += pstx_status->txfail;
540 priv->stats.txretrycount += pstx_status->txretry;
541 priv->stats.txfeedbackretry += pstx_status->txretry;
543 //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length;
544 //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length;
545 //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++;
547 priv->stats.txmulticast += pstx_status->txmcok;
548 priv->stats.txbroadcast += pstx_status->txbcok;
549 priv->stats.txunicast += pstx_status->txucok;
551 priv->stats.txerrmulticast += pstx_status->txmcfail;
552 priv->stats.txerrbroadcast += pstx_status->txbcfail;
553 priv->stats.txerrunicast += pstx_status->txucfail;
555 priv->stats.txbytesmulticast += pstx_status->txmclength;
556 priv->stats.txbytesbroadcast += pstx_status->txbclength;
557 priv->stats.txbytesunicast += pstx_status->txuclength;
559 priv->stats.last_packet_rate = pstx_status->rate;
560 } /* cmpk_CountTxStatus */
564 /*-----------------------------------------------------------------------------
565 * Function: cmpk_handle_tx_status()
567 * Overview: Firmware add a new tx feedback status to reduce rx command
568 * packet buffer operation load.
570 * Input: NONE
572 * Output: NONE
574 * Return: NONE
576 * Revised History:
577 * When Who Remark
578 * 05/12/2008 amy Create Version 0 porting from windows code.
580 *---------------------------------------------------------------------------*/
581 static void
582 cmpk_handle_tx_status(
583 struct net_device *dev,
584 u8* pmsg)
586 cmpk_tx_status_t rx_tx_sts; /* */
588 memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
589 /* 2. Use tx feedback info to count TX statistics. */
590 cmpk_count_tx_status(dev, &rx_tx_sts);
592 } /* cmpk_Handle_Tx_Status */
595 /*-----------------------------------------------------------------------------
596 * Function: cmpk_handle_tx_rate_history()
598 * Overview: Firmware add a new tx rate history
600 * Input: NONE
602 * Output: NONE
604 * Return: NONE
606 * Revised History:
607 * When Who Remark
608 * 05/12/2008 amy Create Version 0 porting from windows code.
610 *---------------------------------------------------------------------------*/
611 static void
612 cmpk_handle_tx_rate_history(
613 struct net_device *dev,
614 u8* pmsg)
616 cmpk_tx_rahis_t *ptxrate;
617 // RT_RF_POWER_STATE rtState;
618 u8 i, j;
619 u16 length = sizeof(cmpk_tx_rahis_t);
620 u32 *ptemp;
621 struct r8192_priv *priv = ieee80211_priv(dev);
624 #ifdef ENABLE_PS
625 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
627 // When RF is off, we should not count the packet for hw/sw synchronize
628 // reason, ie. there may be a duration while sw switch is changed and hw
629 // switch is being changed. 2006.12.04, by shien chang.
630 if (rtState == eRfOff)
632 return;
634 #endif
636 ptemp = (u32 *)pmsg;
639 // Do endian transfer to word alignment(16 bits) for windows system.
640 // You must do different endian transfer for linux and MAC OS
642 for (i = 0; i < (length/4); i++)
644 u16 temp1, temp2;
646 temp1 = ptemp[i]&0x0000FFFF;
647 temp2 = ptemp[i]>>16;
648 ptemp[i] = (temp1<<16)|temp2;
651 ptxrate = (cmpk_tx_rahis_t *)pmsg;
653 if (ptxrate == NULL )
655 return;
658 for (i = 0; i < 16; i++)
660 // Collect CCK rate packet num
661 if (i < 4)
662 priv->stats.txrate.cck[i] += ptxrate->cck[i];
664 // Collect OFDM rate packet num
665 if (i< 8)
666 priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
668 for (j = 0; j < 4; j++)
669 priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
672 } /* cmpk_Handle_Tx_Rate_History */
675 /*-----------------------------------------------------------------------------
676 * Function: cmpk_message_handle_rx()
678 * Overview: In the function, we will capture different RX command packet
679 * info. Every RX command packet element has different message
680 * length and meaning in content. We only support three type of RX
681 * command packet now. Please refer to document
682 * ws-06-0063-rtl8190-command-packet-specification.
684 * Input: NONE
686 * Output: NONE
688 * Return: NONE
690 * Revised History:
691 * When Who Remark
692 * 05/06/2008 amy Create Version 0 porting from windows code.
694 *---------------------------------------------------------------------------*/
695 extern u32
696 cmpk_message_handle_rx(
697 struct net_device *dev,
698 struct ieee80211_rx_stats *pstats)
700 // u32 debug_level = DBG_LOUD;
701 struct r8192_priv *priv = ieee80211_priv(dev);
702 int total_length;
703 u8 cmd_length, exe_cnt = 0;
704 u8 element_id;
705 u8 *pcmd_buff;
707 /* 0. Check inpt arguments. If is is a command queue message or pointer is
708 null. */
709 if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
711 /* Print error message. */
712 /*RT_TRACE(COMP_SEND, DebugLevel,
713 ("\n\r[CMPK]-->Err queue id or pointer"));*/
714 return 0; /* This is not a command packet. */
717 /* 1. Read received command packet message length from RFD. */
718 total_length = pstats->Length;
720 /* 2. Read virtual address from RFD. */
721 pcmd_buff = pstats->virtual_address;
723 /* 3. Read command pakcet element id and length. */
724 element_id = pcmd_buff[0];
725 /*RT_TRACE(COMP_SEND, DebugLevel,
726 ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/
728 /* 4. Check every received command packet conent according to different
729 element type. Because FW may aggregate RX command packet to minimize
730 transmit time between DRV and FW.*/
731 // Add a counter to prevent to locked in the loop too long
732 while (total_length > 0 || exe_cnt++ >100)
734 /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */
735 element_id = pcmd_buff[0];
737 switch(element_id)
739 case RX_TX_FEEDBACK:
740 cmpk_handle_tx_feedback (dev, pcmd_buff);
741 cmd_length = CMPK_RX_TX_FB_SIZE;
742 break;
744 case RX_INTERRUPT_STATUS:
745 cmpk_handle_interrupt_status(dev, pcmd_buff);
746 cmd_length = sizeof(cmpk_intr_sta_t);
747 break;
749 case BOTH_QUERY_CONFIG:
750 cmpk_handle_query_config_rx(dev, pcmd_buff);
751 cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
752 break;
754 case RX_TX_STATUS:
755 cmpk_handle_tx_status(dev, pcmd_buff);
756 cmd_length = CMPK_RX_TX_STS_SIZE;
757 break;
759 case RX_TX_PER_PKT_FEEDBACK:
760 // You must at lease add a switch case element here,
761 // Otherwise, we will jump to default case.
762 //DbgPrint("CCX Test\r\n");
763 cmd_length = CMPK_RX_TX_FB_SIZE;
764 break;
766 case RX_TX_RATE_HISTORY:
767 //DbgPrint(" rx tx rate history\r\n");
768 cmpk_handle_tx_rate_history(dev, pcmd_buff);
769 cmd_length = CMPK_TX_RAHIS_SIZE;
770 break;
772 default:
774 RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknow CMD Element\n");
775 return 1; /* This is a command packet. */
777 // 2007/01/22 MH Display received rx command packet info.
778 //cmpk_Display_Message(cmd_length, pcmd_buff);
780 // 2007/01/22 MH Add to display tx statistic.
781 //cmpk_DisplayTxStatistic(pAdapter);
783 /* 2007/03/09 MH Collect sidderent cmd element pkt num. */
784 priv->stats.rxcmdpkt[element_id]++;
786 total_length -= cmd_length;
787 pcmd_buff += cmd_length;
788 } /* while (total_length > 0) */
789 return 1; /* This is a command packet. */
791 } /* CMPK_Message_Handle_Rx */