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