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
30
31
32
33
34
35RT_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
59 RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
60 firmware_init_param(dev);
61
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
75
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
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
109
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
126Failed:
127
128 return rt_status;
129
130
131#endif
132}
133
134static void
135cmpk_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
146
147
148 if (rtState == eRfOff)
149 {
150 return;
151 }
152#endif
153
154#ifdef TODO
155 if(pAdapter->bInHctTest)
156 return;
157#endif
158
159
160
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
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
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
215
216
217
218
219
220static void
221cmpk_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
231
232
233
234
235
236
237#if 0
238
239
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
255
256 memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t));
257
258 cmpk_count_txstatistic(dev, &rx_tx_fb);
259#if 0
260
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
274
275
276
277
278
279}
280
281
282
283
284
285
286
287
288static void
289cmpk_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
299
300
301
302
303
304
305
306
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
316 if( priv->ieee80211->iw_mode == IW_MODE_ADHOC)
317 {
318
319 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
320
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
337
338
339 DMESG("<---- cmpk_handle_interrupt_status()\n");
340
341}
342
343
344
345
346
347
348
349
350static void
351cmpk_handle_query_config_rx(
352 struct net_device *dev,
353 u8* pmsg)
354{
355 cmpk_query_cfg_t rx_query_cfg;
356
357
358
359
360
361
362
363
364
365
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
381
382
383static 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
395
396
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
413
414
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
435
436
437static void
438cmpk_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
446 cmpk_count_tx_status(dev, &rx_tx_sts);
447
448}
449
450
451
452static void
453cmpk_handle_tx_rate_history(
454 struct net_device *dev,
455 u8* pmsg)
456{
457 cmpk_tx_rahis_t *ptxrate;
458
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
469
470
471 if (rtState == eRfOff)
472 {
473 return;
474 }
475#endif
476
477 ptemp = (u32 *)pmsg;
478
479
480
481
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
502 if (i < 4)
503 priv->stats.txrate.cck[i] += ptxrate->cck[i];
504
505
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
518
519
520
521
522
523u32 cmpk_message_handle_rx(struct net_device *dev, struct ieee80211_rx_stats *pstats)
524{
525
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
535
536 if ((pstats== NULL))
537 {
538
539
540
541 return 0;
542 }
543
544
545 total_length = pstats->Length;
546
547
548 pcmd_buff = pstats->virtual_address;
549
550
551 element_id = pcmd_buff[0];
552
553
554
555
556
557
558
559 while (total_length > 0 || exe_cnt++ >100)
560 {
561
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
596
597
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
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;
614 }
615
616
617
618
619
620
621
622 priv->stats.rxcmdpkt[element_id]++;
623
624 total_length -= cmd_length;
625 pcmd_buff += cmd_length;
626 }
627 return 1;
628
629 RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n");
630}
631