1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "r8192E.h"
25#include "r8192E_hw.h"
26#include "r819xE_cmdpkt.h"
27
28
29#define CMPK_DEBOUNCE_CNT 1
30
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62RT_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
86 RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
87 firmware_init_param(dev);
88
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
102
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
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
136
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 }while(frag_offset < buffer_len);
152
153Failed:
154
155 return rt_status;
156
157
158#endif
159}
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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
190
191
192 if (rtState == eRfOff)
193 {
194 return;
195 }
196#endif
197
198#ifdef TODO
199 if(pAdapter->bInHctTest)
200 return;
201#endif
202
203
204
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
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
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}
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
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
289
290
291
292
293
294
295#if 0
296
297
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
313
314 memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
315
316 cmpk_count_txstatistic(dev, &rx_tx_fb);
317#if 0
318
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
332
333
334
335
336
337}
338
339static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
340{
341 struct r8192_priv *priv = ieee80211_priv(dev);
342 u16 tx_rate;
343 {
344
345
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
361
362 }
363
364}
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
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
400
401
402
403
404
405
406
407
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
417 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC)
418 {
419
420 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
421
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
444
445
446 DMESG("<---- cmpk_handle_interrupt_status()\n");
447
448}
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
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
478
479
480
481
482
483
484
485
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}
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
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
528
529
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
546
547
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}
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
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
592 cmpk_count_tx_status(dev, &rx_tx_sts);
593
594}
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
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
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
630
631
632 if (rtState == eRfOff)
633 {
634 return;
635 }
636#endif
637
638 ptemp = (u32 *)pmsg;
639
640
641
642
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
663 if (i < 4)
664 priv->stats.txrate.cck[i] += ptxrate->cck[i];
665
666
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}
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats)
698{
699
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
709
710 if ((pstats== NULL))
711 {
712
713
714
715 return 0;
716 }
717
718
719 total_length = pstats->Length;
720
721
722 pcmd_buff = pstats->virtual_address;
723
724
725 element_id = pcmd_buff[0];
726
727
728
729
730
731
732
733 while (total_length > 0 || exe_cnt++ >100)
734 {
735
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
770
771
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
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
786 RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknow CMD Element\n");
787 return 1;
788 }
789
790
791
792
793
794
795
796 priv->stats.rxcmdpkt[element_id]++;
797
798 total_length -= cmd_length;
799 pcmd_buff += cmd_length;
800 }
801 return 1;
802
803 RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
804}
805