Merge remote branch 'tip/x86/tsc' into fortglx/2.6.38/tip/x86/tsc
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rtl8192e / r819xE_cmdpkt.c
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 */
35 RT_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
126 Failed:
127 //spin_unlock_irqrestore(&priv->tx_lock,flags);
128 return rt_status;
129
130
131 #endif
132 }
133
134 static void
135 cmpk_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 */
220 static void
221 cmpk_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 */
288 static void
289 cmpk_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 */
350 static void
351 cmpk_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 */
383 static 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 */
437 static void
438 cmpk_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 */
452 static void
453 cmpk_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 */
523 u32 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 }