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