Staging: add Realtek 8192 PCI wireless driver
[deliverable/linux.git] / drivers / staging / rtl8192e / r819xE_cmdpkt.c
CommitLineData
ecdfa446
GKH
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/*---------------------------Define Local Constant---------------------------*/
28/* Debug constant*/
29#define CMPK_DEBOUNCE_CNT 1
30/* 2007/10/24 MH Add for printing a range of data. */
31#define CMPK_PRINT(Address)\
32{\
33 unsigned char i;\
34 u32 temp[10];\
35 \
36 memcpy(temp, Address, 40);\
37 for (i = 0; i <40; i+=4)\
38 printk("\r\n %08x", temp[i]);\
39}\
40
41/*---------------------------Define functions---------------------------------*/
42/*-----------------------------------------------------------------------------
43 * Function: cmpk_message_handle_tx()
44 *
45 * Overview: Driver internal module can call the API to send message to
46 * firmware side. For example, you can send a debug command packet.
47 * Or you can send a request for FW to modify RLX4181 LBUS HW bank.
48 * Otherwise, you can change MAC/PHT/RF register by firmware at
49 * run time. We do not support message more than one segment now.
50 *
51 * Input: NONE
52 *
53 * Output: NONE
54 *
55 * Return: NONE
56 *
57 * Revised History:
58 * When Who Remark
59 * 05/06/2008 amy porting from windows code.
60 *
61 *---------------------------------------------------------------------------*/
62 extern RT_STATUS cmpk_message_handle_tx(
63 struct net_device *dev,
64 u8* code_virtual_address,
65 u32 packettype,
66 u32 buffer_len)
67{
68
69 RT_STATUS rt_status = RT_STATUS_SUCCESS;
70#ifdef RTL8192U
71 return rt_status;
72#else
73 struct r8192_priv *priv = ieee80211_priv(dev);
74 u16 frag_threshold;
75 u16 frag_length = 0, frag_offset = 0;
76 rt_firmware *pfirmware = priv->pFirmware;
77 struct sk_buff *skb;
78 unsigned char *seg_ptr;
79 cb_desc *tcb_desc;
80 u8 bLastIniPkt;
81
82 PTX_FWINFO_8190PCI pTxFwInfo = NULL;
83 int i;
84
85 //spin_lock_irqsave(&priv->tx_lock,flags);
86 RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
87 firmware_init_param(dev);
88 //Fragmentation might be required
89 frag_threshold = pfirmware->cmdpacket_frag_thresold;
90 do {
91 if((buffer_len - frag_offset) > frag_threshold) {
92 frag_length = frag_threshold ;
93 bLastIniPkt = 0;
94
95 } else {
96 frag_length =(u16)(buffer_len - frag_offset);
97 bLastIniPkt = 1;
98
99 }
100
101 /* Allocate skb buffer to contain firmware info and tx descriptor info
102 * add 4 to avoid packet appending overflow.
103 * */
104#ifdef RTL8192U
105 skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
106#else
107 skb = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4);
108#endif
109 if(skb == NULL) {
110 rt_status = RT_STATUS_FAILURE;
111 goto Failed;
112 }
113
114 memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
115 tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
116 tcb_desc->queue_index = TXCMD_QUEUE;
117 tcb_desc->bCmdOrInit = packettype;
118 tcb_desc->bLastIniPkt = bLastIniPkt;
119 tcb_desc->pkt_size = frag_length;
120
121#ifdef RTL8192U
122 skb_reserve(skb, USB_HWDESC_HEADER_LEN);
123#endif
124
125 //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom);
126 seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom);
127
128 pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
129 memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
130 memset(pTxFwInfo,0x12,8);
131
132 seg_ptr +=sizeof(TX_FWINFO_8190PCI);
133
134 /*
135 * Transform from little endian to big endian
136 * and pending zero
137 */
138 seg_ptr = skb->tail;
139 for(i=0 ; i < frag_length; i+=4) {
140 *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
141 *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
142 *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
143 *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
144 }
145 skb_put(skb, i);
146 priv->ieee80211->softmac_hard_start_xmit(skb,dev);
147
148 code_virtual_address += frag_length;
149 frag_offset += frag_length;
150
151#if 0
152 {
153 int k;
154 printk("------------tx cmd------------\n");
155 for(k = 0; k<i; k++)
156 printk(" 0x%x",((u8*)buf)[k]);
157 printk("\n");
158 }
159 {
160 int m;
161 printk("-------------cmd desc----------\n");
162 for(m=0;m<32;m++)
163 printk(" 0x%x",((u8*)pdesc)[m]);
164 printk("\n");
165 }
166#endif
167 }while(frag_offset < buffer_len);
168
169Failed:
170 //spin_unlock_irqrestore(&priv->tx_lock,flags);
171 return rt_status;
172
173
174#endif
175} /* CMPK_Message_Handle_Tx */
176
177/*-----------------------------------------------------------------------------
178 * Function: cmpk_counttxstatistic()
179 *
180 * Overview:
181 *
182 * Input: PADAPTER pAdapter - .
183 * CMPK_TXFB_T *psTx_FB - .
184 *
185 * Output: NONE
186 *
187 * Return: NONE
188 *
189 * Revised History:
190 * When Who Remark
191 * 05/12/2008 amy Create Version 0 porting from windows code.
192 *
193 *---------------------------------------------------------------------------*/
194static void
195cmpk_count_txstatistic(
196 struct net_device *dev,
197 cmpk_txfb_t *pstx_fb)
198{
199 struct r8192_priv *priv = ieee80211_priv(dev);
200#ifdef ENABLE_PS
201 RT_RF_POWER_STATE rtState;
202
203 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
204
205 // When RF is off, we should not count the packet for hw/sw synchronize
206 // reason, ie. there may be a duration while sw switch is changed and hw
207 // switch is being changed. 2006.12.04, by shien chang.
208 if (rtState == eRfOff)
209 {
210 return;
211 }
212#endif
213
214#ifdef TODO
215 if(pAdapter->bInHctTest)
216 return;
217#endif
218 /* We can not know the packet length and transmit type: broadcast or uni
219 or multicast. So the relative statistics must be collected in tx
220 feedback info. */
221 if (pstx_fb->tok)
222 {
223 priv->stats.txfeedbackok++;
224 priv->stats.txoktotal++;
225 priv->stats.txokbytestotal += pstx_fb->pkt_length;
226 priv->stats.txokinperiod++;
227
228 /* We can not make sure broadcast/multicast or unicast mode. */
229 if (pstx_fb->pkt_type == PACKET_MULTICAST)
230 {
231 priv->stats.txmulticast++;
232 priv->stats.txbytesmulticast += pstx_fb->pkt_length;
233 }
234 else if (pstx_fb->pkt_type == PACKET_BROADCAST)
235 {
236 priv->stats.txbroadcast++;
237 priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
238 }
239 else
240 {
241 priv->stats.txunicast++;
242 priv->stats.txbytesunicast += pstx_fb->pkt_length;
243 }
244 }
245 else
246 {
247 priv->stats.txfeedbackfail++;
248 priv->stats.txerrtotal++;
249 priv->stats.txerrbytestotal += pstx_fb->pkt_length;
250
251 /* We can not make sure broadcast/multicast or unicast mode. */
252 if (pstx_fb->pkt_type == PACKET_MULTICAST)
253 {
254 priv->stats.txerrmulticast++;
255 }
256 else if (pstx_fb->pkt_type == PACKET_BROADCAST)
257 {
258 priv->stats.txerrbroadcast++;
259 }
260 else
261 {
262 priv->stats.txerrunicast++;
263 }
264 }
265
266 priv->stats.txretrycount += pstx_fb->retry_cnt;
267 priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
268
269} /* cmpk_CountTxStatistic */
270
271
272
273/*-----------------------------------------------------------------------------
274 * Function: cmpk_handle_tx_feedback()
275 *
276 * Overview: The function is responsible for extract the message inside TX
277 * feedbck message from firmware. It will contain dedicated info in
278 * ws-06-0063-rtl8190-command-packet-specification. Please
279 * refer to chapter "TX Feedback Element". We have to read 20 bytes
280 * in the command packet.
281 *
282 * Input: struct net_device * dev
283 * u8 * pmsg - Msg Ptr of the command packet.
284 *
285 * Output: NONE
286 *
287 * Return: NONE
288 *
289 * Revised History:
290 * When Who Remark
291 * 05/08/2008 amy Create Version 0 porting from windows code.
292 *
293 *---------------------------------------------------------------------------*/
294static void
295cmpk_handle_tx_feedback(
296 struct net_device *dev,
297 u8 * pmsg)
298{
299 struct r8192_priv *priv = ieee80211_priv(dev);
300 cmpk_txfb_t rx_tx_fb; /* */
301
302 priv->stats.txfeedback++;
303
304 /* 0. Display received message. */
305 //cmpk_Display_Message(CMPK_RX_TX_FB_SIZE, pMsg);
306
307 /* 1. Extract TX feedback info from RFD to temp structure buffer. */
308 /* It seems that FW use big endian(MIPS) and DRV use little endian in
309 windows OS. So we have to read the content byte by byte or transfer
310 endian type before copy the message copy. */
311#if 0 // The TX FEEDBACK packet element address
312 //rx_tx_fb.Element_ID = pMsg[0];
313 //rx_tx_fb.Length = pMsg[1];
314 rx_tx_fb.TOK = pMsg[2]>>7;
315 rx_tx_fb.Fail_Reason = (pMsg[2] & 0x70) >> 4;
316 rx_tx_fb.TID = (pMsg[2] & 0x0F);
317 rx_tx_fb.Qos_Pkt = pMsg[3] >> 7;
318 rx_tx_fb.Bandwidth = (pMsg[3] & 0x40) >> 6;
319 rx_tx_fb.Retry_Cnt = pMsg[5];
320 rx_tx_fb.Pkt_ID = (pMsg[6] << 8) | pMsg[7];
321 rx_tx_fb.Seq_Num = (pMsg[8] << 8) | pMsg[9];
322 rx_tx_fb.S_Rate = pMsg[10];
323 rx_tx_fb.F_Rate = pMsg[11];
324 rx_tx_fb.S_RTS_Rate = pMsg[12];
325 rx_tx_fb.F_RTS_Rate = pMsg[13];
326 rx_tx_fb.pkt_length = (pMsg[14] << 8) | pMsg[15];
327#endif
328 /* 2007/07/05 MH Use pointer to transfer structure memory. */
329 //memcpy((UINT8 *)&rx_tx_fb, pMsg, sizeof(CMPK_TXFB_T));
330 memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
331 /* 2. Use tx feedback info to count TX statistics. */
332 cmpk_count_txstatistic(dev, &rx_tx_fb);
333#if 0
334 /* 2007/07/11 MH Assign current operate rate. */
335 if (pAdapter->RegWirelessMode == WIRELESS_MODE_A ||
336 pAdapter->RegWirelessMode == WIRELESS_MODE_B ||
337 pAdapter->RegWirelessMode == WIRELESS_MODE_G)
338 {
339 pMgntInfo->CurrentOperaRate = (rx_tx_fb.F_Rate & 0x7F);
340 }
341 else if (pAdapter->RegWirelessMode == WIRELESS_MODE_N_24G ||
342 pAdapter->RegWirelessMode == WIRELESS_MODE_N_5G)
343 {
344 pMgntInfo->HTCurrentOperaRate = (rx_tx_fb.F_Rate & 0x8F);
345 }
346#endif
347 /* 2007/01/17 MH Comment previous method for TX statistic function. */
348 /* Collect info TX feedback packet to fill TCB. */
349 /* We can not know the packet length and transmit type: broadcast or uni
350 or multicast. */
351 //CountTxStatistics( pAdapter, &tcb );
352
353} /* cmpk_Handle_Tx_Feedback */
354
355void
356cmdpkt_beacontimerinterrupt_819xusb(
357 struct net_device *dev
358)
359{
360 struct r8192_priv *priv = ieee80211_priv(dev);
361 u16 tx_rate;
362 {
363 //
364 // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn.
365 //
366 if((priv->ieee80211->current_network.mode == IEEE_A) ||
367 (priv->ieee80211->current_network.mode == IEEE_N_5G) ||
368 ((priv->ieee80211->current_network.mode == IEEE_N_24G) && (!priv->ieee80211->pHTInfo->bCurSuppCCK)))
369 {
370 tx_rate = 60;
371 DMESG("send beacon frame tx rate is 6Mbpm\n");
372 }
373 else
374 {
375 tx_rate =10;
376 DMESG("send beacon frame tx rate is 1Mbpm\n");
377 }
378
379 //rtl819xusb_beacon_tx(dev,tx_rate); // HW Beacon
380
381 }
382
383}
384
385
386
387
388/*-----------------------------------------------------------------------------
389 * Function: cmpk_handle_interrupt_status()
390 *
391 * Overview: The function is responsible for extract the message from
392 * firmware. It will contain dedicated info in
393 * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc.
394 * Please refer to chapter "Interrupt Status Element".
395 *
396 * Input: struct net_device *dev,
397 * u8* pmsg - Message Pointer of the command packet.
398 *
399 * Output: NONE
400 *
401 * Return: NONE
402 *
403 * Revised History:
404 * When Who Remark
405 * 05/12/2008 amy Add this for rtl8192 porting from windows code.
406 *
407 *---------------------------------------------------------------------------*/
408static void
409cmpk_handle_interrupt_status(
410 struct net_device *dev,
411 u8* pmsg)
412{
413 cmpk_intr_sta_t rx_intr_status; /* */
414 struct r8192_priv *priv = ieee80211_priv(dev);
415
416 DMESG("---> cmpk_Handle_Interrupt_Status()\n");
417
418 /* 0. Display received message. */
419 //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
420
421 /* 1. Extract TX feedback info from RFD to temp structure buffer. */
422 /* It seems that FW use big endian(MIPS) and DRV use little endian in
423 windows OS. So we have to read the content byte by byte or transfer
424 endian type before copy the message copy. */
425 //rx_bcn_state.Element_ID = pMsg[0];
426 //rx_bcn_state.Length = pMsg[1];
427 rx_intr_status.length = pmsg[1];
428 if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2))
429 {
430 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
431 return;
432 }
433
434
435 // Statistics of beacon for ad-hoc mode.
436 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC)
437 {
438 //2 maybe need endian transform?
439 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
440 //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4)));
441
442 DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status);
443
444 if (rx_intr_status.interrupt_status & ISR_TxBcnOk)
445 {
446 priv->ieee80211->bibsscoordinator = true;
447 priv->stats.txbeaconokint++;
448 }
449 else if (rx_intr_status.interrupt_status & ISR_TxBcnErr)
450 {
451 priv->ieee80211->bibsscoordinator = false;
452 priv->stats.txbeaconerr++;
453 }
454
455 if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr)
456 {
457 cmdpkt_beacontimerinterrupt_819xusb(dev);
458 }
459
460 }
461
462 // Other informations in interrupt status we need?
463
464
465 DMESG("<---- cmpk_handle_interrupt_status()\n");
466
467} /* cmpk_handle_interrupt_status */
468
469
470/*-----------------------------------------------------------------------------
471 * Function: cmpk_handle_query_config_rx()
472 *
473 * Overview: The function is responsible for extract the message from
474 * firmware. It will contain dedicated info in
475 * ws-06-0063-rtl8190-command-packet-specification. Please
476 * refer to chapter "Beacon State Element".
477 *
478 * Input: u8 * pmsg - Message Pointer of the command packet.
479 *
480 * Output: NONE
481 *
482 * Return: NONE
483 *
484 * Revised History:
485 * When Who Remark
486 * 05/12/2008 amy Create Version 0 porting from windows code.
487 *
488 *---------------------------------------------------------------------------*/
489static void
490cmpk_handle_query_config_rx(
491 struct net_device *dev,
492 u8* pmsg)
493{
494 cmpk_query_cfg_t rx_query_cfg; /* */
495
496 /* 0. Display received message. */
497 //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg);
498
499 /* 1. Extract TX feedback info from RFD to temp structure buffer. */
500 /* It seems that FW use big endian(MIPS) and DRV use little endian in
501 windows OS. So we have to read the content byte by byte or transfer
502 endian type before copy the message copy. */
503 //rx_query_cfg.Element_ID = pMsg[0];
504 //rx_query_cfg.Length = pMsg[1];
505 rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31;
506 rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5;
507 rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3;
508 rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0;
509 rx_query_cfg.cfg_offset = pmsg[7];
510 rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) |
511 (pmsg[10] << 8) | (pmsg[11] << 0);
512 rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) |
513 (pmsg[14] << 8) | (pmsg[15] << 0);
514
515} /* cmpk_Handle_Query_Config_Rx */
516
517
518/*-----------------------------------------------------------------------------
519 * Function: cmpk_count_tx_status()
520 *
521 * Overview: Count aggregated tx status from firmwar of one type rx command
522 * packet element id = RX_TX_STATUS.
523 *
524 * Input: NONE
525 *
526 * Output: NONE
527 *
528 * Return: NONE
529 *
530 * Revised History:
531 * When Who Remark
532 * 05/12/2008 amy Create Version 0 porting from windows code.
533 *
534 *---------------------------------------------------------------------------*/
535static void cmpk_count_tx_status( struct net_device *dev,
536 cmpk_tx_status_t *pstx_status)
537{
538 struct r8192_priv *priv = ieee80211_priv(dev);
539
540#ifdef ENABLE_PS
541
542 RT_RF_POWER_STATE rtstate;
543
544 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
545
546 // When RF is off, we should not count the packet for hw/sw synchronize
547 // reason, ie. there may be a duration while sw switch is changed and hw
548 // switch is being changed. 2006.12.04, by shien chang.
549 if (rtState == eRfOff)
550 {
551 return;
552 }
553#endif
554
555 priv->stats.txfeedbackok += pstx_status->txok;
556 priv->stats.txoktotal += pstx_status->txok;
557
558 priv->stats.txfeedbackfail += pstx_status->txfail;
559 priv->stats.txerrtotal += pstx_status->txfail;
560
561 priv->stats.txretrycount += pstx_status->txretry;
562 priv->stats.txfeedbackretry += pstx_status->txretry;
563
564 //pAdapter->TxStats.NumTxOkBytesTotal += psTx_FB->pkt_length;
565 //pAdapter->TxStats.NumTxErrBytesTotal += psTx_FB->pkt_length;
566 //pAdapter->MgntInfo.LinkDetectInfo.NumTxOkInPeriod++;
567
568 priv->stats.txmulticast += pstx_status->txmcok;
569 priv->stats.txbroadcast += pstx_status->txbcok;
570 priv->stats.txunicast += pstx_status->txucok;
571
572 priv->stats.txerrmulticast += pstx_status->txmcfail;
573 priv->stats.txerrbroadcast += pstx_status->txbcfail;
574 priv->stats.txerrunicast += pstx_status->txucfail;
575
576 priv->stats.txbytesmulticast += pstx_status->txmclength;
577 priv->stats.txbytesbroadcast += pstx_status->txbclength;
578 priv->stats.txbytesunicast += pstx_status->txuclength;
579
580 priv->stats.last_packet_rate = pstx_status->rate;
581} /* cmpk_CountTxStatus */
582
583
584
585/*-----------------------------------------------------------------------------
586 * Function: cmpk_handle_tx_status()
587 *
588 * Overview: Firmware add a new tx feedback status to reduce rx command
589 * packet buffer operation load.
590 *
591 * Input: NONE
592 *
593 * Output: NONE
594 *
595 * Return: NONE
596 *
597 * Revised History:
598 * When Who Remark
599 * 05/12/2008 amy Create Version 0 porting from windows code.
600 *
601 *---------------------------------------------------------------------------*/
602static void
603cmpk_handle_tx_status(
604 struct net_device *dev,
605 u8* pmsg)
606{
607 cmpk_tx_status_t rx_tx_sts; /* */
608
609 memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t));
610 /* 2. Use tx feedback info to count TX statistics. */
611 cmpk_count_tx_status(dev, &rx_tx_sts);
612
613} /* cmpk_Handle_Tx_Status */
614
615
616/*-----------------------------------------------------------------------------
617 * Function: cmpk_handle_tx_rate_history()
618 *
619 * Overview: Firmware add a new tx rate history
620 *
621 * Input: NONE
622 *
623 * Output: NONE
624 *
625 * Return: NONE
626 *
627 * Revised History:
628 * When Who Remark
629 * 05/12/2008 amy Create Version 0 porting from windows code.
630 *
631 *---------------------------------------------------------------------------*/
632static void
633cmpk_handle_tx_rate_history(
634 struct net_device *dev,
635 u8* pmsg)
636{
637 cmpk_tx_rahis_t *ptxrate;
638// RT_RF_POWER_STATE rtState;
639 u8 i, j;
640 u16 length = sizeof(cmpk_tx_rahis_t);
641 u32 *ptemp;
642 struct r8192_priv *priv = ieee80211_priv(dev);
643
644
645#ifdef ENABLE_PS
646 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState));
647
648 // When RF is off, we should not count the packet for hw/sw synchronize
649 // reason, ie. there may be a duration while sw switch is changed and hw
650 // switch is being changed. 2006.12.04, by shien chang.
651 if (rtState == eRfOff)
652 {
653 return;
654 }
655#endif
656
657 ptemp = (u32 *)pmsg;
658
659 //
660 // Do endian transfer to word alignment(16 bits) for windows system.
661 // You must do different endian transfer for linux and MAC OS
662 //
663 for (i = 0; i < (length/4); i++)
664 {
665 u16 temp1, temp2;
666
667 temp1 = ptemp[i]&0x0000FFFF;
668 temp2 = ptemp[i]>>16;
669 ptemp[i] = (temp1<<16)|temp2;
670 }
671
672 ptxrate = (cmpk_tx_rahis_t *)pmsg;
673
674 if (ptxrate == NULL )
675 {
676 return;
677 }
678
679 for (i = 0; i < 16; i++)
680 {
681 // Collect CCK rate packet num
682 if (i < 4)
683 priv->stats.txrate.cck[i] += ptxrate->cck[i];
684
685 // Collect OFDM rate packet num
686 if (i< 8)
687 priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
688
689 for (j = 0; j < 4; j++)
690 priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
691 }
692
693} /* cmpk_Handle_Tx_Rate_History */
694
695
696/*-----------------------------------------------------------------------------
697 * Function: cmpk_message_handle_rx()
698 *
699 * Overview: In the function, we will capture different RX command packet
700 * info. Every RX command packet element has different message
701 * length and meaning in content. We only support three type of RX
702 * command packet now. Please refer to document
703 * ws-06-0063-rtl8190-command-packet-specification.
704 *
705 * Input: NONE
706 *
707 * Output: NONE
708 *
709 * Return: NONE
710 *
711 * Revised History:
712 * When Who Remark
713 * 05/06/2008 amy Create Version 0 porting from windows code.
714 *
715 *---------------------------------------------------------------------------*/
716extern u32
717cmpk_message_handle_rx(
718 struct net_device *dev,
719 struct ieee80211_rx_stats *pstats)
720{
721// u32 debug_level = DBG_LOUD;
722 struct r8192_priv *priv = ieee80211_priv(dev);
723 int total_length;
724 u8 cmd_length, exe_cnt = 0;
725 u8 element_id;
726 u8 *pcmd_buff;
727
728 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx()\n");
729
730 /* 0. Check inpt arguments. If is is a command queue message or pointer is
731 null. */
732 if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL))
733 {
734 /* Print error message. */
735 /*RT_TRACE(COMP_SEND, DebugLevel,
736 ("\n\r[CMPK]-->Err queue id or pointer"));*/
737 return 0; /* This is not a command packet. */
738 }
739
740 /* 1. Read received command packet message length from RFD. */
741 total_length = pstats->Length;
742
743 /* 2. Read virtual address from RFD. */
744 pcmd_buff = pstats->virtual_address;
745
746 /* 3. Read command pakcet element id and length. */
747 element_id = pcmd_buff[0];
748 /*RT_TRACE(COMP_SEND, DebugLevel,
749 ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/
750
751 /* 4. Check every received command packet conent according to different
752 element type. Because FW may aggregate RX command packet to minimize
753 transmit time between DRV and FW.*/
754 // Add a counter to prevent to locked in the loop too long
755 while (total_length > 0 || exe_cnt++ >100)
756 {
757 /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */
758 element_id = pcmd_buff[0];
759
760 switch(element_id)
761 {
762 case RX_TX_FEEDBACK:
763
764 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n");
765 cmpk_handle_tx_feedback (dev, pcmd_buff);
766 cmd_length = CMPK_RX_TX_FB_SIZE;
767 break;
768
769 case RX_INTERRUPT_STATUS:
770
771 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n");
772 cmpk_handle_interrupt_status(dev, pcmd_buff);
773 cmd_length = sizeof(cmpk_intr_sta_t);
774 break;
775
776 case BOTH_QUERY_CONFIG:
777
778 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n");
779 cmpk_handle_query_config_rx(dev, pcmd_buff);
780 cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
781 break;
782
783 case RX_TX_STATUS:
784
785 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n");
786 cmpk_handle_tx_status(dev, pcmd_buff);
787 cmd_length = CMPK_RX_TX_STS_SIZE;
788 break;
789
790 case RX_TX_PER_PKT_FEEDBACK:
791 // You must at lease add a switch case element here,
792 // Otherwise, we will jump to default case.
793 //DbgPrint("CCX Test\r\n");
794 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n");
795 cmd_length = CMPK_RX_TX_FB_SIZE;
796 break;
797
798 case RX_TX_RATE_HISTORY:
799 //DbgPrint(" rx tx rate history\r\n");
800
801 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n");
802 cmpk_handle_tx_rate_history(dev, pcmd_buff);
803 cmd_length = CMPK_TX_RAHIS_SIZE;
804 break;
805
806 default:
807
808 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknow CMD Element\n");
809 return 1; /* This is a command packet. */
810 }
811 // 2007/01/22 MH Display received rx command packet info.
812 //cmpk_Display_Message(cmd_length, pcmd_buff);
813
814 // 2007/01/22 MH Add to display tx statistic.
815 //cmpk_DisplayTxStatistic(pAdapter);
816
817 /* 2007/03/09 MH Collect sidderent cmd element pkt num. */
818 priv->stats.rxcmdpkt[element_id]++;
819
820 total_length -= cmd_length;
821 pcmd_buff += cmd_length;
822 } /* while (total_length > 0) */
823 return 1; /* This is a command packet. */
824
825 RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
826} /* CMPK_Message_Handle_Rx */
This page took 0.057804 seconds and 5 git commands to generate.