1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "cprecomp.h"
28
29extern u8_t zcUpToAc[8];
30const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0};
31
32
33u16_t aggr_count;
34u32_t success_mpdu;
35u32_t total_mpdu;
36
37void zfAggInit(zdev_t* dev)
38{
39 u16_t i,j;
40
41 zmw_get_wlan_dev(dev);
42
43 zmw_declare_for_critical_section();
44
45
46
47
48 zmw_enter_critical_section(dev);
49 wd->aggInitiated = 0;
50 wd->addbaComplete = 0;
51 wd->addbaCount = 0;
52 wd->reorder = 1;
53 for (i=0; i<ZM_MAX_STA_SUPPORT; i++)
54 {
55 for (j=0; j<ZM_AC; j++)
56 {
57
58 wd->aggSta[i].aggFlag[j] = wd->aggSta[i].count[j] = 0;
59 wd->aggSta[i].tid_tx[j] = NULL;
60 wd->aggSta[i].tid_tx[j+1] = NULL;
61
62 }
63 }
64
65
66
67
68 wd->aggState = 0;
69 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
70 {
71
72
73
74 wd->aggQPool[i] = zfwMemAllocate(dev, sizeof(struct aggQueue));
75 if(!wd->aggQPool[i])
76 {
77 zmw_leave_critical_section(dev);
78 return;
79 }
80 wd->aggQPool[i]->aggHead = wd->aggQPool[i]->aggTail =
81 wd->aggQPool[i]->aggQEnabled = wd->aggQPool[i]->aggReady =
82 wd->aggQPool[i]->clearFlag = wd->aggQPool[i]->deleteFlag = 0;
83
84
85
86
87
88 wd->tid_rx[i] = zfwMemAllocate(dev, sizeof(struct agg_tid_rx));
89 if (!wd->tid_rx[i])
90 {
91 zmw_leave_critical_section(dev);
92 return;
93 }
94 wd->tid_rx[i]->aid = ZM_MAX_STA_SUPPORT;
95 wd->tid_rx[i]->seq_start = wd->tid_rx[i]->baw_head = \
96 wd->tid_rx[i]->baw_tail = 0;
97 wd->tid_rx[i]->sq_exceed_count = wd->tid_rx[i]->sq_behind_count = 0;
98 for (j=0; j<=ZM_AGG_BAW_SIZE; j++)
99 wd->tid_rx[i]->frame[j].buf = 0;
100
101
102
103
104
105
106
107
108 wd->tid_rx[i]->addBaExchangeStatusCode = 0;
109
110 }
111 zmw_leave_critical_section(dev);
112 zfAggTallyReset(dev);
113 DESTQ.init = zfAggDestInit;
114 DESTQ.init(dev);
115 wd->aggInitiated = 1;
116 aggr_count = 0;
117 success_mpdu = 0;
118 total_mpdu = 0;
119#ifdef ZM_ENABLE_AGGREGATION
120#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION
121 BAW = zfwMemAllocate(dev, sizeof(struct baw_enabler));
122 if(!BAW)
123 {
124 return;
125 }
126 BAW->init = zfBawInit;
127 BAW->init(dev);
128#endif
129#endif
130}
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf)
154{
155 u16_t id;
156 u16_t dst[3];
157
158 zmw_get_wlan_dev(dev);
159
160 zmw_declare_for_critical_section();
161
162 dst[0] = zmw_rx_buf_readh(dev, buf, 0);
163 dst[1] = zmw_rx_buf_readh(dev, buf, 2);
164 dst[2] = zmw_rx_buf_readh(dev, buf, 4);
165
166 zmw_enter_critical_section(dev);
167
168 if(wd->wlanMode == ZM_MODE_AP) {
169 id = zfApFindSta(dev, dst);
170 }
171 else {
172 id = 0;
173 }
174 zmw_leave_critical_section(dev);
175
176#if ZM_AGG_FPGA_DEBUG
177 id = 0;
178#endif
179
180 return id;
181}
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid)
203{
204
205 TID_TX tid_tx;
206 zmw_get_wlan_dev(dev);
207
208
209
210
211
212
213 if (0xffff == aid)
214 return NULL;
215
216
217
218 tid_tx = wd->aggSta[aid].tid_tx[tid];
219 if (!tid_tx) return NULL;
220 if (0 == tid_tx->aggQEnabled)
221 return NULL;
222
223
224
225 return tid_tx;
226}
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf)
246{
247 u16_t i;
248 TID_TX tid_tx=NULL;
249 u16_t ac = zcUpToAc[tid&0x7] & 0x3;
250 zmw_get_wlan_dev(dev);
251
252 zmw_declare_for_critical_section();
253
254
255
256
257 if (0xffff == aid)
258 return NULL;
259
260 zmw_enter_critical_section(dev);
261
262
263
264
265 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
266 {
267 if (wd->aggQPool[i]->aggQEnabled)
268 {
269
270
271
272 }
273 else
274 {
275 tid_tx = wd->aggQPool[i];
276 tid_tx->aggQEnabled = 1;
277 tid_tx->aggQSTA = aid;
278 tid_tx->ac = ac;
279 tid_tx->tid = tid;
280 tid_tx->aggHead = tid_tx->aggTail = tid_tx->size = 0;
281 tid_tx->aggReady = 0;
282 wd->aggSta[aid].tid_tx[tid] = tid_tx;
283 tid_tx->dst[0] = zmw_rx_buf_readh(dev, buf, 0);
284 tid_tx->dst[1] = zmw_rx_buf_readh(dev, buf, 2);
285 tid_tx->dst[2] = zmw_rx_buf_readh(dev, buf, 4);
286 break;
287 }
288 }
289
290 zmw_leave_critical_section(dev);
291
292 return tid_tx;
293}
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx)
318{
319
320 u32_t time;
321
322 zmw_get_wlan_dev(dev);
323
324 zmw_declare_for_critical_section();
325
326 zmw_enter_critical_section(dev);
327
328 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
329
330 if (tid_tx->size < (ZM_AGGQ_SIZE - 2))
331 {
332
333
334
335
336
337
338
339
340
341 u8_t sendComplete = 0;
342
343 tid_tx->aggvtxq[tid_tx->aggHead].buf = buf;
344 time = zm_agg_GetTime();
345 tid_tx->aggvtxq[tid_tx->aggHead].arrivalTime = time;
346 tid_tx->aggvtxq[tid_tx->aggHead].baw_retransmit = 0;
347
348 tid_tx->aggHead = ((tid_tx->aggHead + 1) & ZM_AGGQ_SIZE_MASK);
349 tid_tx->lastArrival = time;
350 tid_tx->size++;
351 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
352 if (buf && (tid_tx->size < (ZM_AGGQ_SIZE - 10))) {
353 tid_tx->complete = tid_tx->aggHead;
354 sendComplete = 1;
355 }
356 zmw_leave_critical_section(dev);
357
358 if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) {
359 DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
360 }
361
362 zm_msg1_agg(ZM_LV_0, "tid_tx->size=", tid_tx->size);
363
364
365 if (buf && sendComplete && wd->zfcbSendCompleteIndication) {
366
367 wd->zfcbSendCompleteIndication(dev, buf);
368 }
369
370
371
372
373 return ZM_SUCCESS;
374 }
375 else
376 {
377 zm_msg1_agg(ZM_LV_0, "can't enqueue, tid_tx->size=", tid_tx->size);
378
379
380
381
382
383
384
385
386
387
388
389
390 }
391
392 zmw_leave_critical_section(dev);
393
394 if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) {
395 DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
396 }
397
398 return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
399}
400
401u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq) {
402 struct dest* dest;
403 u16_t exist = 0;
404 zmw_get_wlan_dev(dev);
405
406 zmw_declare_for_critical_section();
407
408 zmw_enter_critical_section(dev);
409 if (!DESTQ.Head[ac]) {
410 exist = 0;
411 }
412 else {
413 dest = DESTQ.Head[ac];
414 if (dest->tid_tx == tid_tx) {
415 exist = 1;
416 }
417 else {
418 while (dest->next != DESTQ.Head[ac]) {
419 dest = dest->next;
420 if (dest->tid_tx == tid_tx){
421 exist = 1;
422 break;
423 }
424 }
425 }
426 }
427
428 zmw_leave_critical_section(dev);
429
430 return exist;
431}
432
433void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq)
434{
435 struct dest* new_dest;
436 zmw_get_wlan_dev(dev);
437
438 zmw_declare_for_critical_section();
439
440 new_dest = zfwMemAllocate(dev, sizeof(struct dest));
441 if(!new_dest)
442 {
443 return;
444 }
445 new_dest->Qtype = Qtype;
446 new_dest->tid_tx = tid_tx;
447 if (0 == Qtype)
448 new_dest->tid_tx = tid_tx;
449 else
450 new_dest->vtxq = vtxq;
451 if (!DESTQ.Head[ac]) {
452
453 zmw_enter_critical_section(dev);
454 new_dest->next = new_dest;
455 DESTQ.Head[ac] = DESTQ.dest[ac] = new_dest;
456 zmw_leave_critical_section(dev);
457 }
458 else {
459
460 zmw_enter_critical_section(dev);
461 new_dest->next = DESTQ.dest[ac]->next;
462 DESTQ.dest[ac]->next = new_dest;
463 zmw_leave_critical_section(dev);
464 }
465
466
467
468 return;
469}
470
471void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq)
472{
473 struct dest* dest, *temp;
474 u16_t i;
475
476 zmw_get_wlan_dev(dev);
477
478 zmw_declare_for_critical_section();
479
480 zmw_enter_critical_section(dev);
481 if (wd->destLock) {
482 zmw_leave_critical_section(dev);
483 return;
484 }
485
486
487
488 for (i=0; i<4; i++) {
489 if (!DESTQ.Head[i]) continue;
490 dest = DESTQ.Head[i];
491 if (!dest) continue;
492
493
494 while (dest && (dest->next != DESTQ.Head[i])) {
495 if (Qtype == 0 && dest->next->tid_tx == tid_tx){
496 break;
497 }
498 if (Qtype == 1 && dest->next->vtxq == vtxq) {
499 break;
500 }
501 dest = dest->next;
502 }
503
504 if ((Qtype == 0 && dest->next->tid_tx == tid_tx) || (Qtype == 1 && dest->next->vtxq == vtxq)) {
505
506 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
507 if (tid_tx->size) {
508 zmw_leave_critical_section(dev);
509 return;
510 }
511 if (!DESTQ.Head[i]) {
512 temp = NULL;
513 }
514 else {
515 temp = dest->next;
516 if (temp == dest) {
517 DESTQ.Head[i] = DESTQ.dest[i] = NULL;
518
519 }
520 else {
521 dest->next = dest->next->next;
522 }
523 }
524
525 if (temp == NULL)
526 {}
527 else
528 zfwMemFree(dev, temp, sizeof(struct dest));
529
530
531
532
533
534
535 }
536
537 }
538 zmw_leave_critical_section(dev);
539 return;
540}
541
542void zfAggDestInit(zdev_t* dev)
543{
544 u16_t i;
545 zmw_get_wlan_dev(dev);
546
547
548
549 for (i=0; i<4; i++) {
550
551
552
553 DESTQ.Head[i] = NULL;
554 }
555 DESTQ.insert = zfAggDestInsert;
556 DESTQ.delete = zfAggDestDelete;
557 DESTQ.init = zfAggDestInit;
558 DESTQ.getNext = zfAggDestGetNext;
559 DESTQ.exist = zfAggDestExist;
560 DESTQ.ppri = 0;
561 return;
562}
563
564struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac)
565{
566 struct dest *dest = NULL;
567 zmw_get_wlan_dev(dev);
568
569 zmw_declare_for_critical_section();
570
571 zmw_enter_critical_section(dev);
572 if (DESTQ.dest[ac]) {
573 dest = DESTQ.dest[ac];
574 DESTQ.dest[ac] = DESTQ.dest[ac]->next;
575 }
576 else {
577 dest = NULL;
578 }
579 zmw_leave_critical_section(dev);
580
581 return dest;
582}
583
584#ifdef ZM_ENABLE_AGGREGATION
585#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION
586u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo *buf_info,TID_TX tid_tx)
587{
588 zbuf_t* buf;
589 u32_t time;
590 struct baw_header *baw_header;
591
592 zmw_get_wlan_dev(dev);
593
594 zmw_declare_for_critical_section();
595
596
597 buf = buf_info->buf;
598
599 zmw_enter_critical_section(dev);
600 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
601 zmw_leave_critical_section(dev);
602
603 if (tid_tx->size >= (ZM_AGGQ_SIZE - 2)) {
604 zfwBufFree(dev, buf, ZM_SUCCESS);
605 return 0;
606 }
607
608 zmw_enter_critical_section(dev);
609 tid_tx->aggTail = (tid_tx->aggTail == 0)? ZM_AGGQ_SIZE_MASK: tid_tx->aggTail - 1;
610 tid_tx->aggvtxq[tid_tx->aggTail].buf = buf;
611
612 tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime = buf_info->timestamp;
613 tid_tx->aggvtxq[tid_tx->aggTail].baw_retransmit = buf_info->baw_retransmit;
614
615 baw_header = &tid_tx->aggvtxq[tid_tx->aggTail].baw_header;
616 baw_header->headerLen = buf_info->baw_header->headerLen;
617 baw_header->micLen = buf_info->baw_header->micLen;
618 baw_header->snapLen = buf_info->baw_header->snapLen;
619 baw_header->removeLen = buf_info->baw_header->removeLen;
620 baw_header->keyIdx = buf_info->baw_header->keyIdx;
621 zfwMemoryCopy((u8_t *)baw_header->header, (u8_t *)buf_info->baw_header->header, 58);
622 zfwMemoryCopy((u8_t *)baw_header->mic , (u8_t *)buf_info->baw_header->mic , 8);
623 zfwMemoryCopy((u8_t *)baw_header->snap , (u8_t *)buf_info->baw_header->snap , 8);
624
625 tid_tx->size++;
626 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
627 zmw_leave_critical_section(dev);
628
629
630 if (1 == tid_tx->size) {
631 DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL);
632 }
633
634
635 zm_msg1_agg(ZM_LV_0, "0xC2:insertHead, tid_tx->size=", tid_tx->size);
636
637 return TRUE;
638}
639#endif
640#endif
641
642void zfiTxComplete(zdev_t* dev)
643{
644
645 zmw_get_wlan_dev(dev);
646
647
648
649 if( (wd->wlanMode == ZM_MODE_AP) ||
650 (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) ||
651 (wd->wlanMode == ZM_MODE_PSEUDO) ) {
652 zfAggTxScheduler(dev, 0);
653 }
654
655 return;
656}
657
658TID_TX zfAggTxReady(zdev_t* dev) {
659
660 u16_t i;
661 TID_TX tid_tx = NULL;
662 zmw_get_wlan_dev(dev);
663
664 zmw_declare_for_critical_section();
665
666 zmw_enter_critical_section(dev);
667 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
668 {
669 if (wd->aggQPool[i]->aggQEnabled)
670 {
671 if (wd->aggQPool[i]->size >= 16) {
672 tid_tx = wd->aggQPool[i];
673 break;
674 }
675 }
676 else {
677 }
678 }
679 zmw_leave_critical_section(dev);
680 return tid_tx;
681}
682
683u16_t zfAggValidTidTx(zdev_t* dev, TID_TX tid_tx) {
684 u16_t i, valid = 0;
685 zmw_get_wlan_dev(dev);
686
687 zmw_declare_for_critical_section();
688
689 zmw_enter_critical_section(dev);
690 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
691 {
692 if (wd->aggQPool[i] == tid_tx)
693 {
694 valid = 1;
695 break;
696 }
697 else {
698 }
699 }
700 zmw_leave_critical_section(dev);
701
702 return valid;
703}
704
705void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear)
706{
707 TID_TX tid_tx = NULL;
708 void* vtxq;
709 struct dest* dest;
710 zbuf_t* buf;
711 u32_t txql, min_txql;
712
713 u16_t txq_threshold;
714 zmw_get_wlan_dev(dev);
715
716 zmw_declare_for_critical_section();
717
718 if (!wd->aggInitiated)
719 {
720 return;
721 }
722
723
724 txql = TXQL;
725 min_txql = AGG_MIN_TXQL;
726
727 if(wd->txq_threshold)
728 txq_threshold = wd->txq_threshold;
729 else
730 txq_threshold = AGG_MIN_TXQL;
731
732 tid_tx = zfAggTxReady(dev);
733 if (tid_tx) ScanAndClear = 0;
734 while (zfHpGetFreeTxdCount(dev) > 20 && (TXQL < txq_threshold || tid_tx)) {
735
736
737 u16_t i;
738 u8_t ac;
739 s8_t destQ_count = 0;
740
741
742
743 for (i=0; i<4; i++) {
744 if (DESTQ.Head[i]) destQ_count++;
745 }
746 if (0 >= destQ_count) break;
747
748 zmw_enter_critical_section(dev);
749 ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10;
750 zmw_leave_critical_section(dev);
751
752 for (i=0; i<10; i++){
753 if(DESTQ.Head[ac]) break;
754
755 zmw_enter_critical_section(dev);
756 ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10;
757 zmw_leave_critical_section(dev);
758 }
759 if (i == 10) break;
760
761 zmw_enter_critical_section(dev);
762 wd->destLock = 1;
763 zmw_leave_critical_section(dev);
764
765 dest = DESTQ.getNext(dev, ac);
766 if (!dest) {
767 zmw_enter_critical_section(dev);
768 wd->destLock = 0;
769 zmw_leave_critical_section(dev);
770
771 DbgPrint("bug report! DESTQ.getNext got nothing!");
772 break;
773 }
774 if (dest->Qtype == 0) {
775 tid_tx = dest->tid_tx;
776
777
778
779 if(tid_tx && zfAggValidTidTx(dev, tid_tx))
780 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
781 else {
782 zmw_enter_critical_section(dev);
783 wd->destLock = 0;
784 zmw_leave_critical_section(dev);
785
786 tid_tx = zfAggTxReady(dev);
787 continue;
788 }
789
790 zmw_enter_critical_section(dev);
791 wd->destLock = 0;
792 zmw_leave_critical_section(dev);
793
794 if (tid_tx && !tid_tx->size) {
795
796
797
798 }
799 else if(wd->aggState == 0){
800
801
802 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
803
804 }
805 else {
806
807 break;
808 }
809 }
810 else {
811 vtxq = dest->vtxq;
812 buf = zfGetVtxq(dev, ac);
813 zm_assert( buf != 0 );
814
815 zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
816
817 }
818
819 tid_tx = zfAggTxReady(dev);
820 }
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853 return;
854}
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid)
879{
880 u16_t aid;
881
882
883
884 TID_TX tid_tx;
885
886 zmw_get_wlan_dev(dev);
887
888 zmw_declare_for_critical_section();
889
890 if(!wd->aggInitiated)
891 {
892 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
893 }
894
895 aid = zfAggGetSta(dev, buf);
896
897
898
899 if (0xffff == aid)
900 {
901
902
903
904
905 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
906 }
907
908
909
910
911
912 tid_tx = zfAggTxGetQueue(dev, aid, tid);
913
914
915
916
917
918 if (tid_tx != NULL)
919 {
920
921
922
923
924
925 if (0)
926 {
927
928
929
930
931
932 zmw_enter_critical_section(dev);
933
934
935
936 zmw_leave_critical_section(dev);
937
938 }
939
940 return zfAggTxEnqueue(dev, buf, aid, tid_tx);
941
942 }
943 else
944 {
945
946
947
948
949
950
951 if (1)
952 {
953
954
955
956
957 tid_tx = zfAggTxNewQueue(dev, aid, tid, buf);
958
959
960
961 if (tid_tx)
962 {
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986 return zfAggTxEnqueue(dev, buf, aid, tid_tx);
987
988 }
989 else
990 {
991
992
993
994
995 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
996 }
997 }
998 else
999 {
1000
1001
1002
1003
1004 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1005 }
1006 }
1007
1008
1009
1010}
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac)
1032{
1033 u16_t i;
1034 u16_t readycount = 0;
1035
1036 zmw_get_wlan_dev(dev);
1037
1038 zmw_declare_for_critical_section();
1039
1040 zmw_enter_critical_section(dev);
1041
1042 for (i=0 ; i<ZM_AGG_POOL_SIZE; i++)
1043 {
1044 if (wd->aggQPool[i]->aggQEnabled && (wd->aggQPool[i]->aggReady || \
1045 wd->aggQPool[i]->clearFlag) && ac == wd->aggQPool[i]->ac)
1046 readycount++;
1047 }
1048
1049 zmw_leave_critical_section(dev);
1050
1051 return readycount;
1052}
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount)
1075{
1076 u16_t qlen;
1077 u16_t partial;
1078
1079 zmw_get_wlan_dev(dev);
1080
1081 zmw_declare_for_critical_section();
1082
1083 zmw_enter_critical_section(dev);
1084
1085 qlen = zm_agg_qlen(dev, wd->vtxqHead[ac], wd->vtxqTail[ac]);
1086
1087 if ((qlen + readycount) > 0)
1088 {
1089 partial = (u16_t)( zm_agg_weight(ac) * ((u16_t)qlen/(qlen + \
1090 readycount)) );
1091 }
1092 else
1093 {
1094 partial = 0;
1095 }
1096
1097 zmw_leave_critical_section(dev);
1098
1099 if (partial > qlen)
1100 partial = qlen;
1101
1102 return partial;
1103}
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx)
1126{
1127
1128
1129 u16_t j;
1130
1131 zbuf_t* buf;
1132 struct aggControl aggControl;
1133 u16_t aggLen;
1134
1135
1136
1137
1138
1139 zmw_get_wlan_dev(dev);
1140
1141 zmw_declare_for_critical_section();
1142
1143
1144
1145 zmw_enter_critical_section(dev);
1146 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1147 aggLen = zm_agg_min(16, zm_agg_min(tid_tx->size, (u16_t)(freeTxd - 2)));
1148 zmw_leave_critical_section(dev);
1149
1150
1151
1152
1153 if (aggLen <=0 )
1154 return 0;
1155
1156
1157 if (aggLen == 1) {
1158 buf = zfAggTxGetVtxq(dev, tid_tx);
1159 if (buf)
1160 zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
1161 if (tid_tx->size == 0) {
1162
1163 }
1164
1165 return 1;
1166 }
1167
1168
1169
1170 zmw_enter_critical_section(dev);
1171 if (wd->aggState == 1) {
1172 zmw_leave_critical_section(dev);
1173 return 0;
1174 }
1175 wd->aggState = 1;
1176 zmw_leave_critical_section(dev);
1177
1178
1179 zm_msg1_agg(ZM_LV_0, "aggLen=", aggLen);
1180 tid_tx->aggFrameSize = 0;
1181 for (j=0; j < aggLen; j++) {
1182 buf = zfAggTxGetVtxq(dev, tid_tx);
1183
1184 zmw_enter_critical_section(dev);
1185 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1186 zmw_leave_critical_section(dev);
1187
1188 if ( buf ) {
1189
1190 u16_t completeIndex;
1191
1192 if (0 == j) {
1193 aggControl.ampduIndication = ZM_AGG_FIRST_MPDU;
1194
1195 }
1196 else if ((j == (aggLen - 1)) || tid_tx->size == 0)
1197 {
1198 aggControl.ampduIndication = ZM_AGG_LAST_MPDU;
1199
1200
1201 }
1202 else
1203 {
1204 aggControl.ampduIndication = ZM_AGG_MIDDLE_MPDU;
1205
1206
1207 }
1208 tid_tx->aggFrameSize += zfwBufGetSize(dev, buf);
1209 aggControl.addbaIndication = 0;
1210 aggControl.aggEnabled = 1;
1211
1212#ifdef ZM_AGG_TALLY
1213 agg_tal = &wd->agg_tal;
1214 agg_tal->sent_packets_sum++;
1215
1216#endif
1217
1218 zfAggTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0, &aggControl, tid_tx);
1219
1220 zmw_enter_critical_section(dev);
1221 completeIndex = tid_tx->complete;
1222 if(zm_agg_inQ(tid_tx, tid_tx->complete))
1223 zm_agg_plus(tid_tx->complete);
1224 zmw_leave_critical_section(dev);
1225
1226 if(zm_agg_inQ(tid_tx, completeIndex) && wd->zfcbSendCompleteIndication
1227 && tid_tx->aggvtxq[completeIndex].buf) {
1228 wd->zfcbSendCompleteIndication(dev, tid_tx->aggvtxq[completeIndex].buf);
1229 zm_debug_msg0("in queue complete worked!");
1230 }
1231
1232 }
1233 else {
1234
1235
1236
1237 zm_msg1_agg(ZM_LV_0, "aggLen not reached, but no more frame, j=", j);
1238
1239 break;
1240 }
1241 }
1242 zmw_enter_critical_section(dev);
1243 wd->aggState = 0;
1244 zmw_leave_critical_section(dev);
1245
1246
1247 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1248
1249
1250 if (tid_tx->size == 0) {
1251
1252 }
1253
1254
1255
1256
1257 if(j>0) {
1258 aggr_count++;
1259 zm_msg1_agg(ZM_LV_0, "0xC2:sent 1 aggr, aggr_count=", aggr_count);
1260 zm_msg1_agg(ZM_LV_0, "0xC2:sent 1 aggr, aggr_size=", j);
1261 }
1262 return j;
1263}
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac)
1286{
1287
1288 u16_t i;
1289 u32_t time = 0;
1290 TID_TX tid_tx = NULL;
1291
1292 zmw_get_wlan_dev(dev);
1293
1294 zmw_declare_for_critical_section();
1295
1296 zmw_enter_critical_section(dev);
1297
1298 for (i=0 ;i<ZM_AGG_POOL_SIZE; i++)
1299 {
1300 if (1 == wd->aggQPool[i]->aggQEnabled && ac == wd->aggQPool[i]->ac &&
1301 (wd->aggQPool[i]->size > 0))
1302 {
1303 if (0 == time || time > wd->aggQPool[i]->aggvtxq[ \
1304 wd->aggQPool[i]->aggHead ].arrivalTime)
1305 {
1306 tid_tx = wd->aggQPool[i];
1307 time = tid_tx->aggvtxq[ tid_tx->aggHead ].arrivalTime;
1308 }
1309 }
1310 }
1311
1312 zmw_leave_critical_section(dev);
1313
1314 return tid_tx;
1315}
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx)
1337{
1338 zbuf_t* buf = NULL;
1339
1340 zmw_declare_for_critical_section();
1341
1342 if (tid_tx->aggHead != tid_tx->aggTail)
1343 {
1344 buf = tid_tx->aggvtxq[ tid_tx->aggTail ].buf;
1345
1346 tid_tx->aggvtxq[tid_tx->aggTail].buf = NULL;
1347
1348 zmw_enter_critical_section(dev);
1349 tid_tx->aggTail = ((tid_tx->aggTail + 1) & ZM_AGGQ_SIZE_MASK);
1350 if(tid_tx->size > 0) tid_tx->size--;
1351 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1352 if (NULL == buf) {
1353
1354
1355 }
1356 zmw_leave_critical_section(dev);
1357 }
1358 else
1359 {
1360
1361
1362
1363 zm_msg1_agg(ZM_LV_0, "tid_tx->aggHead == tid_tx->aggTail, tid_tx->size=", tid_tx->size);
1364
1365 }
1366
1367 if (zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail) != tid_tx->size)
1368 zm_msg1_agg(ZM_LV_0, "qlen!=tid_tx->size! tid_tx->size=", tid_tx->size);
1369 return buf;
1370}
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum)
1392{
1393 u16_t ac, tid;
1394 struct aggQueue *tx_tid;
1395 struct aggSta *agg_sta;
1396
1397 zmw_get_wlan_dev(dev);
1398
1399 zmw_declare_for_critical_section();
1400
1401 tx_tid = wd->aggQPool[qnum];
1402 agg_sta = &wd->aggSta[tx_tid->aggQSTA];
1403 ac = tx_tid->ac;
1404 tid = tx_tid->tid;
1405
1406 zmw_enter_critical_section(dev);
1407
1408 tx_tid->aggQEnabled = 0;
1409 tx_tid->aggHead = tx_tid->aggTail = 0;
1410 tx_tid->aggReady = 0;
1411 tx_tid->clearFlag = tx_tid->deleteFlag = 0;
1412 tx_tid->size = 0;
1413 agg_sta->count[ac] = 0;
1414
1415 agg_sta->tid_tx[tid] = NULL;
1416 agg_sta->aggFlag[ac] = 0;
1417
1418 zmw_leave_critical_section(dev);
1419
1420 zm_msg1_agg(ZM_LV_0, "queue deleted! qnum=", qnum);
1421
1422 return ZM_SUCCESS;
1423}
1424
1425#ifdef ZM_ENABLE_AGGREGATION
1426#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION
1427void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen) {
1428 TID_BAW tid_baw;
1429 s16_t i;
1430 zbuf_t* buf;
1431 struct bufInfo *buf_info;
1432
1433 zmw_get_wlan_dev(dev);
1434
1435 tid_baw = BAW->getQ(dev, baw_seq);
1436
1437 if (NULL == tid_baw)
1438 return;
1439
1440 total_mpdu += aggLen;
1441 for (i = aggLen - 1; i>=0; i--) {
1442 if (((bitmap >> i) & 0x1) == 0) {
1443 buf_info = BAW->pop(dev, i, tid_baw);
1444 buf = buf_info->buf;
1445 if (buf) {
1446
1447 zfAggTidTxInsertHead(dev, buf_info, tid_baw->tid_tx);
1448 }
1449 }
1450 else {
1451 success_mpdu++;
1452 }
1453 }
1454 BAW->disable(dev, tid_baw);
1455 zfAggTxScheduler(dev);
1456 zm_debug_msg1("success_mpdu = ", success_mpdu);
1457 zm_debug_msg1(" total_mpdu = ", total_mpdu);
1458}
1459
1460void zfBawInit(zdev_t* dev) {
1461 TID_BAW tid_baw;
1462 u16_t i,j;
1463 zmw_get_wlan_dev(dev);
1464
1465
1466 for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1467 tid_baw = &BAW->tid_baw[i];
1468 for (j=0; j<ZM_VTXQ_SIZE; j++) {
1469 tid_baw->frame[j].buf = NULL;
1470 }
1471 tid_baw->enabled = tid_baw->head = tid_baw->tail = tid_baw->size = 0;
1472 tid_baw->start_seq = 0;
1473 }
1474 BAW->delPoint = 0;
1475 BAW->core = zfBawCore;
1476 BAW->getNewQ = zfBawGetNewQ;
1477 BAW->insert = zfBawInsert;
1478 BAW->pop = zfBawPop;
1479 BAW->enable = zfBawEnable;
1480 BAW->disable = zfBawDisable;
1481 BAW->getQ = zfBawGetQ;
1482}
1483
1484
1485
1486TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx) {
1487 TID_BAW tid_baw=NULL;
1488 TID_BAW next_baw=NULL;
1489 u16_t i;
1490 zmw_get_wlan_dev(dev);
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501 tid_baw = &BAW->tid_baw[BAW->delPoint];
1502 i = BAW->delPoint;
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512 zm_msg1_agg(ZM_LV_0, "get new tid_baw, index=", i);
1513 BAW->delPoint = (i < (ZM_BAW_POOL_SIZE -1))? (i + 1): 0;
1514 next_baw = &BAW->tid_baw[BAW->delPoint];
1515 if (1 == next_baw->enabled) BAW->disable(dev, next_baw);
1516
1517 BAW->enable(dev, tid_baw, start_seq);
1518 tid_baw->tid_tx = tid_tx;
1519
1520 return tid_baw;
1521}
1522
1523u16_t zfBawInsert(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r) {
1524
1525
1526
1527
1528
1529
1530 if(tid_baw->size < (ZM_VTXQ_SIZE - 1)) {
1531 struct baw_header *baw_header = &tid_baw->frame[tid_baw->head].baw_header;
1532
1533 baw_header->headerLen = header_r->headerLen;
1534 baw_header->micLen = header_r->micLen;
1535 baw_header->snapLen = header_r->snapLen;
1536 baw_header->removeLen = header_r->removeLen;
1537 baw_header->keyIdx = header_r->keyIdx;
1538 zfwMemoryCopy((u8_t *)baw_header->header, (u8_t *)header_r->header, 58);
1539 zfwMemoryCopy((u8_t *)baw_header->mic , (u8_t *)header_r->mic , 8);
1540 zfwMemoryCopy((u8_t *)baw_header->snap , (u8_t *)header_r->snap , 8);
1541
1542 tid_baw->frame[tid_baw->head].buf = buf;
1543 tid_baw->frame[tid_baw->head].baw_seq = baw_seq;
1544 tid_baw->frame[tid_baw->head].baw_retransmit = baw_retransmit + 1;
1545
1546
1547 tid_baw->head++;
1548 tid_baw->size++;
1549 }
1550 else {
1551
1552 zfwBufFree(dev, buf, ZM_SUCCESS);
1553 return FALSE;
1554 }
1555 return TRUE;
1556}
1557
1558struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw) {
1559
1560
1561 struct bufInfo *buf_info;
1562 zmw_get_wlan_dev(dev);
1563
1564 buf_info = &wd->buf_info;
1565 buf_info->baw_header = NULL;
1566
1567 if (NULL == (buf_info->buf = tid_baw->frame[index].buf))
1568 return buf_info;
1569
1570 buf_info->baw_retransmit = tid_baw->frame[index].baw_retransmit;
1571 buf_info->baw_header = &tid_baw->frame[index].baw_header;
1572 buf_info->timestamp = tid_baw->frame[index].timestamp;
1573
1574
1575 tid_baw->frame[index].buf = NULL;
1576
1577 return buf_info;
1578}
1579
1580void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq) {
1581
1582
1583
1584
1585
1586 tid_baw->enabled = TRUE;
1587 tid_baw->head = tid_baw->tail = tid_baw->size = 0;
1588 tid_baw->start_seq = start_seq;
1589}
1590
1591void zfBawDisable(zdev_t* dev, TID_BAW tid_baw) {
1592
1593 u16_t i;
1594
1595
1596
1597 for (i=0; i<ZM_VTXQ_SIZE; i++) {
1598 if (tid_baw->frame[i].buf) {
1599
1600
1601 zfwBufFree(dev, tid_baw->frame[i].buf, ZM_SUCCESS);
1602 tid_baw->frame[i].buf = NULL;
1603 }
1604 }
1605
1606 tid_baw->enabled = FALSE;
1607}
1608
1609TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq) {
1610 TID_BAW tid_baw=NULL;
1611 u16_t i;
1612
1613 zmw_get_wlan_dev(dev);
1614
1615 for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1616 tid_baw = &BAW->tid_baw[i];
1617 if (TRUE == tid_baw->enabled)
1618 {
1619 zm_msg1_agg(ZM_LV_0, "get an old tid_baw, baw_seq=", baw_seq);
1620 zm_msg1_agg(ZM_LV_0, "check a tid_baw->start_seq=", tid_baw->start_seq);
1621 if(baw_seq == tid_baw->start_seq)
1622 break;
1623 }
1624
1625 }
1626 if (ZM_BAW_POOL_SIZE == i)
1627 return NULL;
1628 return tid_baw;
1629}
1630#endif
1631#endif
1632
1633u16_t zfAggTallyReset(zdev_t* dev)
1634{
1635 struct aggTally* agg_tal;
1636
1637 zmw_get_wlan_dev(dev);
1638
1639
1640
1641 agg_tal = &wd->agg_tal;
1642 agg_tal->got_packets_sum = 0;
1643 agg_tal->got_bytes_sum = 0;
1644 agg_tal->sent_bytes_sum = 0;
1645 agg_tal->sent_packets_sum = 0;
1646 agg_tal->avg_got_packets = 0;
1647 agg_tal->avg_got_bytes = 0;
1648 agg_tal->avg_sent_packets = 0;
1649 agg_tal->avg_sent_bytes = 0;
1650 agg_tal->time = 0;
1651 return 0;
1652}
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672u16_t zfAggScanAndClear(zdev_t* dev, u32_t time)
1673{
1674 u16_t i;
1675 u16_t head;
1676 u16_t tail;
1677 u32_t tick;
1678 u32_t arrivalTime;
1679
1680 TID_TX tid_tx;
1681
1682 zmw_get_wlan_dev(dev);
1683
1684 zmw_declare_for_critical_section();
1685
1686 if(!(wd->state == ZM_WLAN_STATE_ENABLED)) return 0;
1687 zfAggTxScheduler(dev, 1);
1688 tick = zm_agg_GetTime();
1689 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
1690 {
1691 if (!wd->aggQPool[i]) return 0;
1692 if (1 == wd->aggQPool[i]->aggQEnabled)
1693 {
1694 tid_tx = wd->aggQPool[i];
1695 zmw_enter_critical_section(dev);
1696
1697 head = tid_tx->aggHead;
1698 tail = tid_tx->aggTail;
1699
1700 arrivalTime = (u32_t)tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime;
1701
1702
1703 if((tick - arrivalTime) <= ZM_AGG_CLEAR_TIME)
1704 {
1705
1706 }
1707 else if((tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail)) > 0)
1708 {
1709
1710 tid_tx->clearFlag = 1;
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720 }
1721
1722 if (tid_tx->size == 0)
1723 {
1724
1725
1726
1727 if (tick - tid_tx->lastArrival > ZM_AGG_DELETE_TIME)
1728 {
1729 zm_msg1_agg(ZM_LV_0, "delete queue, idle for n sec. n = ", \
1730 ZM_AGG_DELETE_TIME/10);
1731
1732 zmw_leave_critical_section(dev);
1733 zfAggTxDeleteQueue(dev, i);
1734 zmw_enter_critical_section(dev);
1735 }
1736 }
1737
1738 zmw_leave_critical_section(dev);
1739 }
1740 }
1741
1742 zfAggRxClear(dev, time);
1743
1744#ifdef ZM_AGG_TALLY
1745 if((wd->tick % 100) == 0) {
1746 zfAggPrintTally(dev);
1747 }
1748#endif
1749
1750 return ZM_SUCCESS;
1751}
1752
1753u16_t zfAggPrintTally(zdev_t* dev)
1754{
1755 struct aggTally* agg_tal;
1756
1757 zmw_get_wlan_dev(dev);
1758
1759
1760
1761 agg_tal = &wd->agg_tal;
1762
1763 if(agg_tal->got_packets_sum < 10)
1764 {
1765 zfAggTallyReset(dev);
1766 return 0;
1767 }
1768
1769 agg_tal->time++;
1770 agg_tal->avg_got_packets = (agg_tal->avg_got_packets * (agg_tal->time - 1) +
1771 agg_tal->got_packets_sum) / agg_tal->time;
1772 agg_tal->avg_got_bytes = (agg_tal->avg_got_bytes * (agg_tal->time - 1) +
1773 agg_tal->got_bytes_sum) / agg_tal->time;
1774 agg_tal->avg_sent_packets = (agg_tal->avg_sent_packets * (agg_tal->time - 1)
1775 + agg_tal->sent_packets_sum) / agg_tal->time;
1776 agg_tal->avg_sent_bytes = (agg_tal->avg_sent_bytes * (agg_tal->time - 1) +
1777 agg_tal->sent_bytes_sum) / agg_tal->time;
1778 zm_msg1_agg(ZM_LV_0, "got_packets_sum =", agg_tal->got_packets_sum);
1779 zm_msg1_agg(ZM_LV_0, " got_bytes_sum =", agg_tal->got_bytes_sum);
1780 zm_msg1_agg(ZM_LV_0, "sent_packets_sum=", agg_tal->sent_packets_sum);
1781 zm_msg1_agg(ZM_LV_0, " sent_bytes_sum =", agg_tal->sent_bytes_sum);
1782 agg_tal->got_packets_sum = agg_tal->got_bytes_sum =agg_tal->sent_packets_sum
1783 = agg_tal->sent_bytes_sum = 0;
1784 zm_msg1_agg(ZM_LV_0, "avg_got_packets =", agg_tal->avg_got_packets);
1785 zm_msg1_agg(ZM_LV_0, " avg_got_bytes =", agg_tal->avg_got_bytes);
1786 zm_msg1_agg(ZM_LV_0, "avg_sent_packets=", agg_tal->avg_sent_packets);
1787 zm_msg1_agg(ZM_LV_0, " avg_sent_bytes =", agg_tal->avg_sent_bytes);
1788 if ((wd->commTally.BA_Fail == 0) || (wd->commTally.Hw_Tx_MPDU == 0))
1789 {
1790 zm_msg1_agg(ZM_LV_0, "Hardware Tx MPDU=", wd->commTally.Hw_Tx_MPDU);
1791 zm_msg1_agg(ZM_LV_0, " BA Fail number=", wd->commTally.BA_Fail);
1792 }
1793 else
1794 zm_msg1_agg(ZM_LV_0, "1/(BA fail rate)=", wd->commTally.Hw_Tx_MPDU/wd->commTally.BA_Fail);
1795
1796 return 0;
1797}
1798
1799u16_t zfAggRxClear(zdev_t* dev, u32_t time)
1800{
1801 u16_t i;
1802 struct agg_tid_rx *tid_rx;
1803
1804 zmw_get_wlan_dev(dev);
1805
1806 zmw_declare_for_critical_section();
1807
1808 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
1809 {
1810 zmw_enter_critical_section(dev);
1811 tid_rx = wd->tid_rx[i];
1812 if (tid_rx->baw_head != tid_rx->baw_tail)
1813 {
1814 u16_t j = tid_rx->baw_tail;
1815 while ((j != tid_rx->baw_head) && !tid_rx->frame[j].buf) {
1816 j = (j + 1) & ZM_AGG_BAW_MASK;
1817 }
1818 if ((j != tid_rx->baw_head) && (time - tid_rx->frame[j].arrivalTime) >
1819 (ZM_AGG_CLEAR_TIME - 5))
1820 {
1821 zmw_leave_critical_section(dev);
1822 zm_msg0_agg(ZM_LV_1, "queue RxFlush by RxClear");
1823 zfAggRxFlush(dev, 0, tid_rx);
1824 zmw_enter_critical_section(dev);
1825 }
1826 }
1827 zmw_leave_critical_section(dev);
1828 }
1829
1830 return ZM_SUCCESS;
1831}
1832
1833struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
1834{
1835 u16_t dst0, src[3], ac, aid, fragOff;
1836 u8_t up;
1837 u16_t offset = 0;
1838 u16_t seq_no;
1839 u16_t frameType;
1840 u16_t frameCtrl;
1841 u16_t frameSubtype;
1842 u32_t tcp_seq;
1843
1844#if ZM_AGG_FPGA_REORDERING
1845 struct agg_tid_rx *tid_rx;
1846#endif
1847 zmw_get_wlan_dev(dev);
1848
1849
1850 seq_no = zmw_rx_buf_readh(dev, buf, 22) >> 4;
1851
1852 if (wd->sta.EnableHT == 0)
1853 {
1854 return NULL;
1855 }
1856
1857 frameCtrl = zmw_rx_buf_readb(dev, buf, 0);
1858 frameType = frameCtrl & 0xf;
1859 frameSubtype = frameCtrl & 0xf0;
1860
1861
1862 if (frameType != ZM_WLAN_DATA_FRAME)
1863 {
1864 return NULL;
1865 }
1866#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1867 tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
1868 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
1869 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
1870 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
1871#endif
1872
1873 ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
1874 dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
1875
1876 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
1877 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
1878 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
1879
1880#if ZM_AGG_FPGA_DEBUG
1881 aid = 0;
1882#else
1883 aid = zfApFindSta(dev, src);
1884#endif
1885
1886
1887
1888
1889
1890
1891
1892
1893 if ((dst0 & 0x1) == 0 && aid == 0)
1894 {
1895#if ZM_AGG_FPGA_REORDERING
1896 tid_rx = zfAggRxGetQueue(dev, buf) ;
1897 if(!tid_rx)
1898 return NULL;
1899 else
1900 {
1901
1902 return tid_rx;
1903 }
1904#else
1905 return NULL;
1906#endif
1907 }
1908
1909 return NULL;
1910}
1911
1912u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx)
1913{
1914 u16_t seq_no;
1915 s16_t index;
1916 u16_t offset = 0;
1917 zbuf_t* pbuf;
1918 u8_t frameSubType;
1919
1920 zmw_get_wlan_dev(dev);
1921
1922 zmw_declare_for_critical_section();
1923
1924 ZM_BUFFER_TRACE(dev, buf)
1925
1926 ZM_PERFORMANCE_RX_REORDER(dev);
1927
1928 seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1929
1930 index = seq_no - tid_rx->seq_start;
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946 frameSubType = (zmw_rx_buf_readh(dev, buf, 0) & 0xF0) >> 4;
1947
1948
1949 if ((frameSubType & 0x0C) == 0x04)
1950 {
1951 s16_t seq_diff;
1952
1953 seq_diff = (seq_no > tid_rx->seq_start) ?
1954 seq_no - tid_rx->seq_start : tid_rx->seq_start - seq_no;
1955
1956 if (seq_diff > ZM_AGG_BAW_SIZE)
1957 {
1958 zm_debug_msg0("Free Rx NULL data in zfAggRx");
1959
1960
1961 zfwBufFree(dev, buf, 0);
1962 return ZM_ERR_OUT_OF_ORDER_NULL_DATA;
1963 }
1964 }
1965
1966
1967
1968
1969 if (tid_rx->seq_start > seq_no)
1970 {
1971
1972
1973 zmw_enter_critical_section(dev);
1974 if (tid_rx->seq_start >= 4096) {
1975 tid_rx->seq_start = 0;
1976 }
1977 zmw_leave_critical_section(dev);
1978
1979 }
1980
1981 if (tid_rx->seq_start == seq_no) {
1982 zmw_enter_critical_section(dev);
1983 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) > 0) {
1984
1985 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
1986 }
1987 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
1988 zmw_leave_critical_section(dev);
1989
1990 ZM_PERFORMANCE_RX_SEQ(dev, buf);
1991
1992 if (wd->zfcbRecv80211 != NULL) {
1993
1994
1995
1996
1997 wd->zfcbRecv80211(dev, buf, addInfo);
1998 }
1999 else {
2000 zfiRecv80211(dev, buf, addInfo);
2001 }
2002 }
2003 else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo))
2004 {
2005
2006
2007
2008 return 1;
2009 }
2010
2011 while (tid_rx->baw_head != tid_rx->baw_tail) {
2012 u16_t tailIndex;
2013
2014 zmw_enter_critical_section(dev);
2015
2016 tailIndex = tid_rx->baw_tail;
2017 pbuf = tid_rx->frame[tailIndex].buf;
2018 tid_rx->frame[tailIndex].buf = 0;
2019 if (!pbuf)
2020 {
2021 zmw_leave_critical_section(dev);
2022 break;
2023 }
2024
2025 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2026 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2027
2028
2029
2030
2031
2032 zmw_leave_critical_section(dev);
2033
2034 ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2035
2036 if (wd->zfcbRecv80211 != NULL)
2037 {
2038
2039
2040
2041 wd->zfcbRecv80211(dev, pbuf, addInfo);
2042 }
2043 else
2044 {
2045
2046
2047 zfiRecv80211(dev, pbuf, addInfo);
2048 }
2049 }
2050
2051 return 1;
2052}
2053
2054struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf)
2055{
2056 u16_t src[3];
2057 u16_t aid, ac, i;
2058 u16_t offset = 0;
2059 struct agg_tid_rx *tid_rx = NULL;
2060
2061 zmw_get_wlan_dev(dev);
2062
2063
2064
2065 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
2066 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
2067 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
2068 aid = zfApFindSta(dev, src);
2069
2070 ac = (zmw_rx_buf_readh(dev, buf, 24) & 0xF);
2071
2072
2073
2074
2075 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
2076 {
2077 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
2078 {
2079 tid_rx = wd->tid_rx[i];
2080 break;
2081 }
2082 }
2083
2084
2085
2086 return tid_rx;
2087}
2088
2089
2090u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo)
2091{
2092 u16_t seq_no, offset = 0;
2093 u16_t q_index;
2094 s16_t index;
2095 u8_t bdropframe = 0;
2096
2097 zmw_get_wlan_dev(dev);
2098
2099 zmw_declare_for_critical_section();
2100
2101 ZM_BUFFER_TRACE(dev, buf)
2102
2103 seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2104 index = seq_no - tid_rx->seq_start;
2105
2106
2107
2108
2109
2110 bdropframe = 0;
2111 if (tid_rx->seq_start > seq_no) {
2112 if ((tid_rx->seq_start > 3967) && (seq_no < 128)) {
2113 index += 4096;
2114 } else if (tid_rx->seq_start - seq_no > 70) {
2115 zmw_enter_critical_section(dev);
2116 tid_rx->sq_behind_count++;
2117 if (tid_rx->sq_behind_count > 3) {
2118 tid_rx->sq_behind_count = 0;
2119 } else {
2120 bdropframe = 1;
2121 }
2122 zmw_leave_critical_section(dev);
2123 } else {
2124 bdropframe = 1;
2125 }
2126 } else {
2127 if (seq_no - tid_rx->seq_start > 70) {
2128 zmw_enter_critical_section(dev);
2129 tid_rx->sq_exceed_count++;
2130 if (tid_rx->sq_exceed_count > 3) {
2131 tid_rx->sq_exceed_count = 0;
2132 } else {
2133 bdropframe = 1;
2134 }
2135 zmw_leave_critical_section(dev);
2136 }
2137 }
2138
2139 if (bdropframe == 1) {
2140
2141
2142
2143
2144
2145
2146
2147 ZM_PERFORMANCE_FREE(dev, buf);
2148
2149 zfwBufFree(dev, buf, 0);
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161 return 0;
2162 } else {
2163 zmw_enter_critical_section(dev);
2164 if (tid_rx->sq_exceed_count > 0){
2165 tid_rx->sq_exceed_count--;
2166 }
2167
2168 if (tid_rx->sq_behind_count > 0) {
2169 tid_rx->sq_behind_count--;
2170 }
2171 zmw_leave_critical_section(dev);
2172 }
2173
2174 if (index < 0) {
2175 zfAggRxFlush(dev, seq_no, tid_rx);
2176 tid_rx->seq_start = seq_no;
2177 index = 0;
2178 }
2179
2180
2181 if (index >= (ZM_AGG_BAW_MASK))
2182 {
2183
2184
2185
2186
2187 zfAggRxFlush(dev, seq_no, tid_rx);
2188
2189 index = seq_no - tid_rx->seq_start;
2190 if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2191 {
2192
2193 index += 4096;
2194 }
2195
2196 while (index >= (ZM_AGG_BAW_MASK)) {
2197
2198 tid_rx->seq_start = (tid_rx->seq_start + ZM_AGG_BAW_MASK) & (4096 - 1);
2199 index = seq_no - tid_rx->seq_start;
2200 if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2201 {
2202 index += 4096;
2203 }
2204 }
2205 }
2206
2207
2208 q_index = (tid_rx->baw_tail + index) & ZM_AGG_BAW_MASK;
2209 if (tid_rx->frame[q_index].buf && (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) >
2210 (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK)))
2211 {
2212
2213 ZM_PERFORMANCE_DUP(dev, tid_rx->frame[q_index].buf, buf);
2214 zfwBufFree(dev, buf, 0);
2215
2216
2217
2218
2219
2220 return 0;
2221 }
2222
2223 zmw_enter_critical_section(dev);
2224 if(tid_rx->frame[q_index].buf) {
2225 zfwBufFree(dev, tid_rx->frame[q_index].buf, 0);
2226 tid_rx->frame[q_index].buf = 0;
2227 }
2228
2229 tid_rx->frame[q_index].buf = buf;
2230 tid_rx->frame[q_index].arrivalTime = zm_agg_GetTime();
2231 zfwMemoryCopy((void*)&tid_rx->frame[q_index].addInfo, (void*)addInfo, sizeof(struct zsAdditionInfo));
2232
2233
2234
2235
2236
2237
2238
2239
2240 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= index)
2241 {
2242
2243 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <=
2244
2245 (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK))
2246 tid_rx->baw_head = (q_index + 1) & ZM_AGG_BAW_MASK;
2247 }
2248 zmw_leave_critical_section(dev);
2249
2250
2251
2252
2253
2254 return 1;
2255}
2256
2257u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx)
2258{
2259 zbuf_t* pbuf;
2260 u16_t seq;
2261 struct zsAdditionInfo addInfo;
2262 zmw_get_wlan_dev(dev);
2263 zmw_declare_for_critical_section();
2264
2265 ZM_PERFORMANCE_RX_FLUSH(dev);
2266
2267 while (1)
2268 {
2269 zmw_enter_critical_section(dev);
2270 if (tid_rx->baw_tail == tid_rx->baw_head) {
2271 zmw_leave_critical_section(dev);
2272 break;
2273 }
2274
2275 pbuf = tid_rx->frame[tid_rx->baw_tail].buf;
2276 zfwMemoryCopy((void*)&addInfo, (void*)&tid_rx->frame[tid_rx->baw_tail].addInfo, sizeof(struct zsAdditionInfo));
2277 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2278
2279 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2280 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2281 zmw_leave_critical_section(dev);
2282
2283 if (pbuf)
2284 {
2285
2286 ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2287
2288 if (wd->zfcbRecv80211 != NULL)
2289 {
2290 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2291
2292
2293 wd->zfcbRecv80211(dev, pbuf, &addInfo);
2294 }
2295 else
2296 {
2297 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2298
2299 zfiRecv80211(dev, pbuf, &addInfo);
2300 }
2301 }
2302 }
2303
2304 zmw_enter_critical_section(dev);
2305 tid_rx->baw_head = tid_rx->baw_tail = 0;
2306 zmw_leave_critical_section(dev);
2307 return 1;
2308}
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy)
2329{
2330 u16_t i;
2331 zbuf_t* buf;
2332 struct agg_tid_rx *tid_rx;
2333
2334 TID_TX tid_tx;
2335
2336
2337 zmw_get_wlan_dev(dev);
2338 zmw_declare_for_critical_section();
2339
2340 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
2341 {
2342 u16_t j;
2343
2344 tid_rx = wd->tid_rx[i];
2345
2346 for(j=0; j <= ZM_AGG_BAW_SIZE; j++)
2347 {
2348 zmw_enter_critical_section(dev);
2349 buf = tid_rx->frame[j].buf;
2350 tid_rx->frame[j].buf = 0;
2351 zmw_leave_critical_section(dev);
2352
2353 if (buf)
2354 {
2355 zfwBufFree(dev, buf, 0);
2356 }
2357 }
2358
2359 #if 0
2360 if ( tid_rx->baw_head != tid_rx->baw_tail )
2361 {
2362 while (tid_rx->baw_head != tid_rx->baw_tail)
2363 {
2364 buf = tid_rx->frame[tid_rx->baw_tail].buf;
2365 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2366 if (buf)
2367 {
2368 zfwBufFree(dev, buf, 0);
2369
2370 zmw_enter_critical_section(dev);
2371 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2372 zmw_leave_critical_section(dev);
2373 }
2374 zmw_enter_critical_section(dev);
2375
2376 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2377 tid_rx->seq_start++;
2378 zmw_leave_critical_section(dev);
2379 }
2380 }
2381 #endif
2382
2383 zmw_enter_critical_section(dev);
2384 tid_rx->seq_start = 0;
2385 tid_rx->baw_head = tid_rx->baw_tail = 0;
2386 tid_rx->aid = ZM_MAX_STA_SUPPORT;
2387 zmw_leave_critical_section(dev);
2388
2389 #ifdef ZM_ENABLE_AGGREGATION
2390 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION
2391 if (tid_baw->enabled) {
2392 zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2393 BAW->disable(dev, tid_baw);
2394 }
2395 #endif
2396 #endif
2397 if (1 == wd->aggQPool[i]->aggQEnabled) {
2398 tid_tx = wd->aggQPool[i];
2399 buf = zfAggTxGetVtxq(dev, tid_tx);
2400 while (buf) {
2401 zfwBufFree(dev, buf, 0);
2402 buf = zfAggTxGetVtxq(dev, tid_tx);
2403 }
2404 }
2405
2406 if(destroy) {
2407 zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2408 zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2409 }
2410 }
2411 #ifdef ZM_ENABLE_AGGREGATION
2412 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION
2413 if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2414 #endif
2415 #endif
2416 return ZM_SUCCESS;
2417}
2418
2419
2420void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2421 u16_t start_seq, len;
2422 u8_t i, bitmap[8];
2423 len = zfwBufGetSize(dev, buf);
2424 start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2425 DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2426
2427 for (i=0; i<8; i++) bitmap[i]=0;
2428 zfSendBA(dev, start_seq, bitmap);
2429}
2430
2431#ifdef ZM_ENABLE_AGGREGATION
2432#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION
2433void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2434 u16_t removeLen;
2435 u16_t err;
2436
2437 zmw_get_wlan_dev(dev);
2438 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2439 tid_tx->bar_ssn = buf_info->baw_header->header[15];
2440 aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2441 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2442 }
2443 buf_info->baw_header->header[4] |= (1 << 11);
2444 if (aggControl && aggControl->aggEnabled) {
2445
2446
2447
2448
2449
2450 buf_info->baw_header->header[1] |= 0x20;
2451 if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2452 buf_info->baw_header->header[1] |= 0x4000;
2453 }
2454 else {
2455 buf_info->baw_header->header[1] &= ~0x4000;
2456
2457 }
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469 }
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486 if ((err = zfHpSend(dev,
2487 buf_info->baw_header->header,
2488 buf_info->baw_header->headerLen,
2489 buf_info->baw_header->snap,
2490 buf_info->baw_header->snapLen,
2491 buf_info->baw_header->mic,
2492 buf_info->baw_header->micLen,
2493 buf_info->buf,
2494 buf_info->baw_header->removeLen,
2495 ZM_EXTERNAL_ALLOC_BUF,
2496 (u8_t)tid_tx->ac,
2497 buf_info->baw_header->keyIdx)) != ZM_SUCCESS)
2498 {
2499 goto zlError;
2500 }
2501
2502 return;
2503
2504zlError:
2505 zfwBufFree(dev, buf_info->buf, 0);
2506 return;
2507
2508}
2509#endif
2510#endif
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx)
2529{
2530 u16_t err;
2531
2532
2533 u16_t removeLen;
2534 u16_t header[(8+30+2+18)/2];
2535 u16_t headerLen;
2536 u16_t mic[8/2];
2537 u16_t micLen;
2538 u16_t snap[8/2];
2539 u16_t snapLen;
2540 u16_t fragLen;
2541 u16_t frameLen;
2542 u16_t fragNum;
2543 struct zsFrag frag;
2544 u16_t i, id;
2545 u16_t da[3];
2546 u16_t sa[3];
2547 u8_t up;
2548 u8_t qosType, keyIdx = 0;
2549 u16_t fragOff;
2550
2551 zmw_get_wlan_dev(dev);
2552
2553 zmw_declare_for_critical_section();
2554
2555 zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2556
2557
2558 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2559
2560#ifdef ZM_ENABLE_NATIVE_WIFI
2561 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2562 {
2563
2564 da[0] = zmw_tx_buf_readh(dev, buf, 16);
2565 da[1] = zmw_tx_buf_readh(dev, buf, 18);
2566 da[2] = zmw_tx_buf_readh(dev, buf, 20);
2567
2568 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2569 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2570 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2571 }
2572 else if ( wd->wlanMode == ZM_MODE_IBSS )
2573 {
2574
2575 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2576 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2577 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2578
2579 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2580 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2581 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2582 }
2583 else if ( wd->wlanMode == ZM_MODE_AP )
2584 {
2585
2586 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2587 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2588 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2589
2590 sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2591 sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2592 sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2593 }
2594 else
2595 {
2596
2597 }
2598#else
2599
2600 da[0] = zmw_tx_buf_readh(dev, buf, 0);
2601 da[1] = zmw_tx_buf_readh(dev, buf, 2);
2602 da[2] = zmw_tx_buf_readh(dev, buf, 4);
2603
2604 sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2605 sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2606 sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2607#endif
2608
2609 if (wd->wlanMode == ZM_MODE_AP)
2610 {
2611 keyIdx = wd->ap.bcHalKeyIdx[port];
2612 id = zfApFindSta(dev, da);
2613 if (id != 0xffff)
2614 {
2615 switch (wd->ap.staTable[id].encryMode)
2616 {
2617 case ZM_AES:
2618 case ZM_TKIP:
2619#ifdef ZM_ENABLE_CENC
2620 case ZM_CENC:
2621#endif
2622 keyIdx = wd->ap.staTable[id].keyIdx;
2623 break;
2624 }
2625 }
2626 }
2627 else
2628 {
2629 switch (wd->sta.encryMode)
2630 {
2631 case ZM_WEP64:
2632 case ZM_WEP128:
2633 case ZM_WEP256:
2634 keyIdx = wd->sta.keyId;
2635 break;
2636 case ZM_AES:
2637 case ZM_TKIP:
2638 if ((da[0]& 0x1))
2639 keyIdx = 5;
2640 else
2641 keyIdx = 4;
2642 break;
2643#ifdef ZM_ENABLE_CENC
2644 case ZM_CENC:
2645 keyIdx = wd->sta.cencKeyId;
2646 break;
2647#endif
2648 }
2649 }
2650
2651
2652 removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2653
2654
2655 fragLen = wd->fragThreshold;
2656 frameLen = zfwBufGetSize(dev, buf);
2657 frameLen -= removeLen;
2658
2659#if 0
2660
2661 if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
2662 (wd->sta.encryMode == ZM_TKIP) )
2663 {
2664 if ( frameLen > fragLen )
2665 {
2666 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2667 }
2668 else
2669 {
2670
2671 micLen = 8;
2672 }
2673 }
2674 else
2675 {
2676 micLen = 0;
2677 }
2678#else
2679 if ( frameLen > fragLen )
2680 {
2681 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2682 }
2683 else
2684 {
2685
2686 micLen = 0;
2687 }
2688#endif
2689
2690
2691 if (wd->wlanMode == ZM_MODE_AP)
2692 {
2693 zfApGetStaQosType(dev, da, &qosType);
2694 if (qosType == 0)
2695 {
2696 up = 0;
2697 }
2698 }
2699 else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2700 {
2701 if (wd->sta.wmeConnected == 0)
2702 {
2703 up = 0;
2704 }
2705 }
2706 else
2707 {
2708
2709 up = 0;
2710 }
2711
2712
2713 zmw_enter_critical_section(dev);
2714 frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2715 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2716 tid_tx->bar_ssn = frag.seq[0];
2717
2718 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2719 }
2720
2721 zmw_leave_critical_section(dev);
2722
2723
2724 frag.buf[0] = buf;
2725 frag.bufType[0] = bufType;
2726 frag.flag[0] = flag;
2727 fragNum = 1;
2728
2729 for (i=0; i<fragNum; i++)
2730 {
2731
2732 if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2733 headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2734 frag.flag[i], snapLen+micLen, removeLen,
2735 port, da, sa, up, &micLen, snap, snapLen,
2736 aggControl);
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749#if 0
2750 zm_msg1_tx(ZM_LV_0, "headerLen=", headerLen);
2751 zm_msg1_tx(ZM_LV_0, "snapLen=", snapLen);
2752 zm_msg1_tx(ZM_LV_0, "micLen=", micLen);
2753 zm_msg1_tx(ZM_LV_0, "removeLen=", removeLen);
2754 zm_msg1_tx(ZM_LV_0, "addrTblSize=", addrTblSize);
2755 zm_msg1_tx(ZM_LV_0, "frag.bufType[0]=", frag.bufType[0]);
2756#endif
2757
2758 fragLen = zfwBufGetSize(dev, frag.buf[i]);
2759 if ((da[0]&0x1) == 0)
2760 {
2761 wd->commTally.txUnicastFrm++;
2762 wd->commTally.txUnicastOctets += (fragLen+snapLen);
2763 }
2764 else if ((da[0]& 0x1))
2765 {
2766 wd->commTally.txBroadcastFrm++;
2767 wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2768 }
2769 else
2770 {
2771 wd->commTally.txMulticastFrm++;
2772 wd->commTally.txMulticastOctets += (fragLen+snapLen);
2773 }
2774 wd->ledStruct.txTraffic++;
2775
2776#if 0
2777 if ( (i)&&(i == (fragNum-1)) )
2778 {
2779 wd->trafTally.txDataByteCount -= micLen;
2780 }
2781#endif
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798 if ((err = zfHpSend(dev, header, headerLen, snap, snapLen,
2799 mic, micLen, frag.buf[i], removeLen,
2800 frag.bufType[i], zcUpToAc[up&0x7], keyIdx)) != ZM_SUCCESS)
2801 {
2802 goto zlError;
2803 }
2804
2805
2806 continue;
2807
2808zlError:
2809 if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2810 {
2811 zfwBufFree(dev, frag.buf[i], err);
2812 }
2813 else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2814 {
2815 zfwBufFree(dev, frag.buf[i], 0);
2816 }
2817 else
2818 {
2819 zm_assert(0);
2820 }
2821 }
2822
2823 return ZM_SUCCESS;
2824}
2825
2826
2827
2828
2829u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2830{
2831 zbuf_t* buf;
2832
2833
2834
2835 u16_t offset = 0;
2836 u16_t hlen = 32;
2837 u16_t header[(24+25+1)/2];
2838 u16_t vap = 0;
2839 u16_t i;
2840 u8_t encrypt = 0;
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
2851 {
2852 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2853 return ZM_SUCCESS;
2854 }
2855
2856
2857
2858
2859 offset = hlen;
2860
2861
2862
2863
2864 offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2865
2866
2867 zfwBufSetSize(dev, buf, offset);
2868
2869
2870
2871
2872 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2873 for (i=0; i<(hlen>>1); i++)
2874 {
2875 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2876 }
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892 #if 0
2893 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
2894 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
2895 {
2896 goto zlError;
2897 }
2898 #else
2899 zfPutVmmq(dev, buf);
2900 zfPushVtxq(dev);
2901 #endif
2902
2903 return ZM_SUCCESS;
2904
2905}
2906
2907u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2908{
2909 u16_t ba_parameter, start_seq;
2910
2911 zmw_get_wlan_dev(dev);
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921 zmw_tx_buf_writeb(dev, buf, offset++, 3);
2922
2923
2924
2925 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2926
2927
2928
2929
2930 zmw_tx_buf_writeb(dev, buf, offset++, 2);
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942 ba_parameter = 1 << 12;
2943 ba_parameter |= up << 2;
2944 ba_parameter |= 2;
2945 zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2946 offset+=2;
2947
2948
2949
2950 zmw_tx_buf_writeh(dev, buf, offset, 0);
2951 offset+=2;
2952
2953
2954
2955
2956
2957
2958
2959
2960 start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2961 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2962 offset+=2;
2963
2964 return offset;
2965}
2966
2967u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2968 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2969{
2970 u8_t hlen = 32;
2971
2972
2973 zmw_get_wlan_dev(dev);
2974
2975 zmw_declare_for_critical_section();
2976
2977
2978
2979
2980
2981 header[0] = 24+len+4;
2982 header[1] = 0x8;
2983
2984#if 0
2985
2986 header[2] = 0x0f00;
2987 header[3] = 0x0000;
2988#else
2989
2990 header[2] = 0x0f01;
2991 header[3] = 0x000B;
2992#endif
2993
2994
2995
2996
2997
2998 header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
2999
3000
3001
3002 header[4+1] = 0;
3003
3004 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
3005 {
3006 header[4+8] = wd->sta.bssid[0];
3007 header[4+9] = wd->sta.bssid[1];
3008 header[4+10] = wd->sta.bssid[2];
3009 }
3010 else if (wd->wlanMode == ZM_MODE_PSEUDO)
3011 {
3012
3013 header[4+8] = 0;
3014 header[4+9] = 0;
3015 header[4+10] = 0;
3016 }
3017 else if (wd->wlanMode == ZM_MODE_IBSS)
3018 {
3019 header[4+8] = wd->sta.bssid[0];
3020 header[4+9] = wd->sta.bssid[1];
3021 header[4+10] = wd->sta.bssid[2];
3022 }
3023 else if (wd->wlanMode == ZM_MODE_AP)
3024 {
3025
3026 header[4+8] = wd->macAddr[0];
3027 header[4+9] = wd->macAddr[1];
3028 header[4+10] = wd->macAddr[2] + (vap<<8);
3029 }
3030
3031
3032 header[4+2] = dst[0];
3033 header[4+3] = dst[1];
3034 header[4+4] = dst[2];
3035
3036
3037 header[4+5] = wd->macAddr[0];
3038 header[4+6] = wd->macAddr[1];
3039 if (wd->wlanMode == ZM_MODE_AP)
3040 {
3041 header[4+7] = wd->macAddr[2] + (vap<<8);
3042 }
3043 else
3044 {
3045 header[4+7] = wd->macAddr[2];
3046 }
3047
3048
3049 zmw_enter_critical_section(dev);
3050 header[4+11] = ((wd->mmseq++)<<4);
3051 zmw_leave_critical_section(dev);
3052
3053
3054 return hlen;
3055}
3056
3057
3058u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
3059{
3060 u16_t category;
3061
3062
3063
3064
3065
3066 category = zmw_rx_buf_readb(dev, buf, 24);
3067
3068 switch (category)
3069 {
3070 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3071 zfAggBlockAckActionFrame(dev, buf);
3072 break;
3073
3074 }
3075
3076 return ZM_SUCCESS;
3077}
3078
3079
3080u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3081{
3082 u8_t action;
3083
3084
3085
3086
3087
3088 action = zmw_rx_buf_readb(dev, buf, 25);
3089#ifdef ZM_ENABLE_AGGREGATION
3090 switch (action)
3091 {
3092 case ZM_WLAN_ADDBA_REQUEST_FRAME:
3093 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3094 zfAggRecvAddbaRequest(dev, buf);
3095 break;
3096 case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3097 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3098 zfAggRecvAddbaResponse(dev, buf);
3099 break;
3100 case ZM_WLAN_DELBA_FRAME:
3101 zfAggRecvDelba(dev, buf);
3102 break;
3103 }
3104#endif
3105 return ZM_SUCCESS;
3106}
3107
3108u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3109{
3110
3111 struct aggBaFrameParameter bf;
3112 u16_t i;
3113
3114
3115
3116
3117 bf.buf = buf;
3118 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3119
3120
3121
3122 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3123 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3124 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3125 bf.buffer_size = (bf.ba_parameter >> 6);
3126
3127
3128
3129 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3130
3131
3132
3133 bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3134
3135 i=26;
3136 while(i < 32) {
3137 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3138 i++;
3139 }
3140
3141 zfAggSendAddbaResponse(dev, &bf);
3142
3143 zfAggAddbaSetTidRx(dev, buf, &bf);
3144
3145 return ZM_SUCCESS;
3146}
3147
3148u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3149{
3150 u16_t i, ac, aid, fragOff;
3151 u16_t src[3];
3152 u16_t offset = 0;
3153 u8_t up;
3154 struct agg_tid_rx *tid_rx = NULL;
3155
3156 zmw_get_wlan_dev(dev);
3157
3158 zmw_declare_for_critical_section();
3159
3160 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3161 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3162 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3163 aid = zfApFindSta(dev, src);
3164
3165 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3166 ac = zcUpToAc[up&0x7] & 0x3;
3167
3168 ac = bf->tid;
3169
3170 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3171 {
3172 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3173 {
3174 tid_rx = wd->tid_rx[i];
3175 break;
3176 }
3177 }
3178
3179 if (!tid_rx)
3180 {
3181 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3182 {
3183 if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3184 {
3185 tid_rx = wd->tid_rx[i];
3186 break;
3187 }
3188 }
3189 if (!tid_rx)
3190 return 0;
3191 }
3192
3193 zmw_enter_critical_section(dev);
3194
3195 tid_rx->aid = aid;
3196 tid_rx->ac = ac;
3197 tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3198 tid_rx->seq_start = bf->ba_start_seq;
3199 tid_rx->baw_head = tid_rx->baw_tail = 0;
3200 tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3201 zmw_leave_critical_section(dev);
3202
3203 return 0;
3204}
3205
3206u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3207{
3208 u16_t i,ac, aid=0;
3209 u16_t src[3];
3210 struct aggBaFrameParameter bf;
3211
3212 zmw_get_wlan_dev(dev);
3213
3214
3215
3216 src[0] = zmw_rx_buf_readh(dev, buf, 10);
3217 src[1] = zmw_rx_buf_readh(dev, buf, 12);
3218 src[2] = zmw_rx_buf_readh(dev, buf, 14);
3219
3220 if (wd->wlanMode == ZM_MODE_AP)
3221 aid = zfApFindSta(dev, src);
3222
3223
3224 bf.buf = buf;
3225 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3226 bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3227 if (!bf.status_code)
3228 {
3229 wd->addbaComplete=1;
3230 }
3231
3232
3233
3234
3235 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3236 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3237 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3238 bf.buffer_size = (bf.ba_parameter >> 6);
3239
3240
3241
3242 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3243
3244 i=26;
3245 while(i < 32) {
3246 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3247 i++;
3248 }
3249
3250 ac = zcUpToAc[bf.tid&0x7] & 0x3;
3251
3252
3253
3254
3255
3256
3257
3258 return ZM_SUCCESS;
3259}
3260
3261u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3262{
3263
3264
3265
3266 return ZM_SUCCESS;
3267}
3268
3269u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3270{
3271 zbuf_t* buf;
3272
3273
3274
3275 u16_t offset = 0;
3276 u16_t hlen = 32;
3277 u16_t header[(24+25+1)/2];
3278 u16_t vap = 0;
3279 u16_t i;
3280 u8_t encrypt = 0;
3281 u16_t dst[3];
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3292 {
3293 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3294 return ZM_SUCCESS;
3295 }
3296
3297
3298
3299
3300 offset = hlen;
3301
3302
3303
3304
3305 offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3306
3307
3308 zfwBufSetSize(dev, buf, offset);
3309
3310
3311
3312
3313
3314 dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3315 dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3316 dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3317 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3318 for (i=0; i<(hlen>>1); i++)
3319 {
3320 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3321 }
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337 #if 0
3338 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3339 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3340 {
3341 goto zlError;
3342 }
3343 #else
3344 zfPutVmmq(dev, buf);
3345 zfPushVtxq(dev);
3346 #endif
3347
3348
3349 return ZM_SUCCESS;
3350
3351}
3352
3353u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3354 struct aggBaFrameParameter *bf, u16_t offset)
3355{
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367 zmw_tx_buf_writeb(dev, buf, offset++, 3);
3368
3369
3370
3371 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3372
3373
3374
3375 zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3376
3377
3378
3379 zmw_tx_buf_writeh(dev, buf, offset, 0);
3380 offset+=2;
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3393 offset+=2;
3394
3395
3396
3397 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3398 offset+=2;
3399
3400 return offset;
3401}
3402
3403void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3404{
3405 struct aggBarControl aggBarControl;
3406
3407
3408
3409
3410
3411 aggBarControl.bar_ack_policy = 0;
3412 aggBarControl.multi_tid = 0;
3413 aggBarControl.compressed_bitmap = 0;
3414 aggBarControl.tid_info = tid_tx->tid;
3415 zfAggSendBar(dev, tid_tx, &aggBarControl);
3416
3417 return;
3418
3419}
3420
3421
3422
3423u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3424{
3425 zbuf_t* buf;
3426
3427
3428
3429 u16_t offset = 0;
3430 u16_t hlen = 16+8;
3431 u16_t header[(8+24+1)/2];
3432 u16_t vap = 0;
3433 u16_t i;
3434 u8_t encrypt = 0;
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444 if ((buf = zfwBufAllocate(dev, 1024)) == NULL)
3445 {
3446 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3447 return ZM_SUCCESS;
3448 }
3449
3450
3451
3452
3453 offset = hlen;
3454
3455
3456
3457
3458 offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3459
3460
3461 zfwBufSetSize(dev, buf, offset);
3462
3463
3464
3465
3466 zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3467 for (i=0; i<(hlen>>1); i++)
3468 {
3469 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3470 }
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486 #if 0
3487 if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3488 ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS)
3489 {
3490 goto zlError;
3491 }
3492 #else
3493 zfPutVmmq(dev, buf);
3494 zfPushVtxq(dev);
3495 #endif
3496
3497 return ZM_SUCCESS;
3498
3499}
3500
3501u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3502{
3503 u16_t bar_control, start_seq;
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521 bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3522 | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3523
3524 zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3525 offset+=2;
3526 if (0 == aggBarControl->multi_tid) {
3527
3528
3529
3530
3531
3532
3533
3534
3535 start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3536 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3537 offset+=2;
3538 }
3539 if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3540
3541 }
3542
3543 return offset;
3544}
3545
3546u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3547 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3548{
3549 u8_t hlen = 16+8;
3550
3551
3552 zmw_get_wlan_dev(dev);
3553
3554 zmw_declare_for_critical_section();
3555
3556
3557
3558
3559
3560 header[0] = 16+len+4;
3561 header[1] = 0x8;
3562
3563#if 1
3564
3565 header[2] = 0x0f00;
3566 header[3] = 0x0000;
3567#else
3568
3569 header[2] = 0x0f01;
3570 header[3] = 0x000B;
3571
3572#endif
3573
3574
3575
3576
3577 header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3578
3579
3580
3581 header[4+1] = 0;
3582
3583
3584 header[4+2] = dst[0];
3585 header[4+3] = dst[1];
3586 header[4+4] = dst[2];
3587
3588
3589 header[4+5] = wd->macAddr[0];
3590 header[4+6] = wd->macAddr[1];
3591 if (wd->wlanMode == ZM_MODE_AP)
3592 {
3593#ifdef ZM_VAPMODE_MULTILE_SSID
3594 header[4+7] = wd->macAddr[2];
3595#else
3596 header[4+7] = wd->macAddr[2] + (vap<<8);
3597#endif
3598 }
3599 else
3600 {
3601 header[4+7] = wd->macAddr[2];
3602 }
3603
3604
3605 zmw_enter_critical_section(dev);
3606 header[4+11] = ((wd->mmseq++)<<4);
3607 zmw_leave_critical_section(dev);
3608
3609
3610 return hlen;
3611}
3612