Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / otus / 80211core / cagg.c
1 /*
2 * Copyright (c) 2007-2008 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16 /* */
17 /* Module Name : cagg.c */
18 /* */
19 /* Abstract */
20 /* This module contains A-MPDU aggregation related functions. */
21 /* */
22 /* NOTES */
23 /* None */
24 /* */
25 /************************************************************************/
26
27 #include "cprecomp.h"
28
29 extern u8_t zcUpToAc[8];
30 const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0};
31
32
33 u16_t aggr_count;
34 u32_t success_mpdu;
35 u32_t total_mpdu;
36
37 void 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 * reset sta information
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 //wd->aggSta[i].aggQNumber[j] = ZM_AGG_POOL_SIZE;
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 * reset Tx/Rx aggregation queue information
67 */
68 wd->aggState = 0;
69 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
70 {
71 /*
72 * reset tx aggregation queue
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 //wd->aggQPool[i]->aggSize = 16;
84
85 /*
86 * reset rx aggregation queue
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 * reset ADDBA exchange status code
102 * 0: NULL
103 * 1: ADDBA Request sent/received
104 * 2: ACK for ADDBA Request sent/received
105 * 3: ADDBA Response sent/received
106 * 4: ACK for ADDBA Response sent/received
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 //disable BAW
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 //disable BAW
129 #endif
130 }
131
132 /************************************************************************/
133 /* */
134 /* FUNCTION DESCRIPTION zfAggGetSta */
135 /* return STA AID. */
136 /* take buf as input, use the dest address of buf as index to */
137 /* search STA AID. */
138 /* */
139 /* INPUTS */
140 /* dev : device pointer */
141 /* buf : buffer for one particular packet */
142 /* */
143 /* OUTPUTS */
144 /* AID */
145 /* */
146 /* AUTHOR */
147 /* Honda ZyDAS Technology Corporation 2006.11 */
148 /* */
149 /************************************************************************/
150
151
152
153 u16_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 /* FUNCTION DESCRIPTION zfAggTxGetQueue */
187 /* return Queue Pool index. */
188 /* take aid as input, look for the queue index associated */
189 /* with this aid. */
190 /* */
191 /* INPUTS */
192 /* dev : device pointer */
193 /* aid : associated id */
194 /* */
195 /* OUTPUTS */
196 /* Queue number */
197 /* */
198 /* AUTHOR */
199 /* Honda ZyDAS Technology Corporation 2006.11 */
200 /* */
201 /************************************************************************/
202 TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid)
203 {
204 //u16_t i;
205 TID_TX tid_tx;
206 zmw_get_wlan_dev(dev);
207
208 //zmw_declare_for_critical_section();
209
210 /*
211 * not a STA aid
212 */
213 if (0xffff == aid)
214 return NULL;
215
216 //zmw_enter_critical_section(dev);
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 //zmw_leave_critical_section(dev);
224
225 return tid_tx;
226 }
227
228 /************************************************************************/
229 /* */
230 /* FUNCTION DESCRIPTION zfAggTxNewQueue */
231 /* return Queue Pool index. */
232 /* take aid as input, find a new queue for this aid. */
233 /* */
234 /* INPUTS */
235 /* dev : device pointer */
236 /* aid : associated id */
237 /* */
238 /* OUTPUTS */
239 /* Queue number */
240 /* */
241 /* AUTHOR */
242 /* Honda ZyDAS Technology Corporation 2006.12 */
243 /* */
244 /************************************************************************/
245 TID_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 * not a STA aid
256 */
257 if (0xffff == aid)
258 return NULL;
259
260 zmw_enter_critical_section(dev);
261
262 /*
263 * find one new queue for sta
264 */
265 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
266 {
267 if (wd->aggQPool[i]->aggQEnabled)
268 {
269 /*
270 * this q is enabled
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 /* FUNCTION DESCRIPTION zfAggTxEnqueue */
300 /* return Status code ZM_SUCCESS or error code */
301 /* take (aid,ac,qnum,buf) as input */
302 /* */
303 /* INPUTS */
304 /* dev : device pointer */
305 /* aid : associated id */
306 /* ac : access category */
307 /* qnum: the queue number to which will be enqueued */
308 /* buf : the packet to be queued */
309 /* */
310 /* OUTPUTS */
311 /* status code */
312 /* */
313 /* AUTHOR */
314 /* Honda Atheros Communications, INC. 2006.12 */
315 /* */
316 /************************************************************************/
317 u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx)
318 {
319 //u16_t qlen, frameLen;
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 /* Queue not full */
333
334
335 /*
336 * buffer copy
337 * in zfwBufFree will return a ndismsendcomplete
338 * to resolve the synchronize problem in aggregate
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 //zm_debug_msg1("tid_tx->size=", tid_tx->size);
364
365 if (buf && sendComplete && wd->zfcbSendCompleteIndication) {
366 //zmw_leave_critical_section(dev);
367 wd->zfcbSendCompleteIndication(dev, buf);
368 }
369
370 /*if (tid_tx->size >= 16 && zfHpGetFreeTxdCount(dev) > 20)
371 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
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 * Queue Full
380 */
381
382 /*
383 * zm_msg1_agg(ZM_LV_0, "Queue full, qnum = ", qnum);
384 * wd->commTally.txQosDropCount[ac]++;
385 * zfwBufFree(dev, buf, ZM_SUCCESS);
386 * zm_msg1_agg(ZM_LV_1, "Packet discarded, VTXQ full, ac=", ac);
387 *
388 * return ZM_ERR_EXCEED_PRIORITY_THRESHOLD;
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
401 u16_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
433 void 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 //DESTQ.size[ac]++;
468 return;
469 }
470
471 void 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 //zmw_declare_for_critical_section();
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 //DESTQ.size[i] = 0;
519 }
520 else {
521 dest->next = dest->next->next;
522 }
523 }
524
525 if (temp == NULL)
526 {/* do nothing */} //zfwMemFree(dev, temp, sizeof(struct dest));
527 else
528 zfwMemFree(dev, temp, sizeof(struct dest));
529
530 /*zmw_enter_critical_section(dev);
531 if (DESTQ.size[i] > 0)
532 DESTQ.size[i]--;
533 zmw_leave_critical_section(dev);
534 */
535 }
536
537 }
538 zmw_leave_critical_section(dev);
539 return;
540 }
541
542 void zfAggDestInit(zdev_t* dev)
543 {
544 u16_t i;
545 zmw_get_wlan_dev(dev);
546
547 //zmw_declare_for_critical_section();
548
549 for (i=0; i<4; i++) {
550 //wd->destQ.Head[i].next = wd->destQ.Head[i];
551 //wd->destQ.dest[i] = wd->destQ.Head[i];
552 //DESTQ.size[i] = 0;
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
564 struct 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 //disable BAW
586 u16_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 //time = zm_agg_GetTime();
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 //tid_tx->lastArrival = time;
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 //disable BAW
640 #endif
641
642 void zfiTxComplete(zdev_t* dev)
643 {
644
645 zmw_get_wlan_dev(dev);
646
647 //zmw_declare_for_critical_section();
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
658 TID_TX zfAggTxReady(zdev_t* dev) {
659 //struct dest* dest;
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
683 u16_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
705 void 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 //u16_t aggr_size = 1;
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 /* debug */
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 //while (zfHpGetFreeTxdCount(dev) > 20 && (ScanAndClear || tid_tx)) {
736 //while (TXQL < txq_threshold) {
737 u16_t i;
738 u8_t ac;
739 s8_t destQ_count = 0;
740 //while ((zfHpGetFreeTxdCount(dev)) > 32) {
741
742 //DbgPrint("zfAggTxScheduler: in while loop");
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 //DbgPrint("zfAggTxScheduler: have dest Q");
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 //DbgPrint("zfAggTxScheduler: have tid_tx Q");
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 //zmw_enter_critical_section(dev);
794 if (tid_tx && !tid_tx->size) {
795
796 //zmw_leave_critical_section(dev);
797 //DESTQ.delete(dev, 0, tid_tx, NULL);
798 }
799 else if(wd->aggState == 0){
800 //wd->aggState = 1;
801 //zmw_leave_critical_section(dev);
802 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
803 //wd->aggState = 0;
804 }
805 else {
806 //zmw_leave_critical_section(dev);
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 /*flush all but < 16 frames in tid_tx to TXQ*/
819 tid_tx = zfAggTxReady(dev);
820 }
821
822 /*while ((zfHpGetFreeTxdCount(dev)) > 32) {
823 //while ((zfHpGetFreeTxdCount(dev)) > 32) {
824
825 destQ_count = 0;
826 for (i=0; i<4; i++) destQ_count += wd->destQ.size[i];
827 if (0 >= destQ_count) break;
828
829 ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10;
830 for (i=0; i<10; i++){
831 if(wd->destQ.size[ac]!=0) break;
832 ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10;
833 }
834 if (i == 10) break;
835 dest = wd->destQ.getNext(dev, ac);
836 if (dest->Qtype == 0) {
837 tid_tx = dest->tid_tx;
838 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
839 if (!tid_tx->size) {
840 wd->destQ.delete(dev, 0, tid_tx, NULL);
841 break;
842 }
843 else if((wd->aggState == 0) && (tid_tx->size >= 16)){
844 zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx);
845 }
846 else {
847 break;
848 }
849 }
850
851 }
852 */
853 return;
854 }
855
856 /************************************************************************/
857 /* */
858 /* FUNCTION DESCRIPTION zfAggTx */
859 /* return Status code ZM_SUCCESS or error code */
860 /* management A-MPDU aggregation function, */
861 /* management aggregation queue, calculate arrivalrate, */
862 /* add/delete an aggregation queue of a stream, */
863 /* enqueue packets into responsible aggregate queue. */
864 /* take (dev, buf, ac) as input */
865 /* */
866 /* INPUTS */
867 /* dev : device pointer */
868 /* buf : packet buff */
869 /* ac : access category */
870 /* */
871 /* OUTPUTS */
872 /* status code */
873 /* */
874 /* AUTHOR */
875 /* Honda Atheros Communications, INC. 2006.12 */
876 /* */
877 /************************************************************************/
878 u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid)
879 {
880 u16_t aid;
881 //u16_t qnum;
882 //u16_t aggflag = 0;
883 //u16_t arrivalrate = 0;
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 //arrivalrate = zfAggTxArrivalRate(dev, aid, tid);
898
899 if (0xffff == aid)
900 {
901 /*
902 * STA not associated, this is a BC/MC or STA->AP packet
903 */
904
905 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
906 }
907
908 /*
909 * STA associated, a unicast packet
910 */
911
912 tid_tx = zfAggTxGetQueue(dev, aid, tid);
913
914 /*tid_q.tid_tx = tid_tx;
915 wd->destQ.insert = zfAggDestInsert;
916 wd->destQ.insert(dev, 0, tid_q);
917 */
918 if (tid_tx != NULL)
919 {
920 /*
921 * this (aid, ac) is aggregated
922 */
923
924 //if (arrivalrate < ZM_AGG_LOW_THRESHOLD)
925 if (0)
926 {
927 /*
928 * arrival rate too low
929 * delete this aggregate queue
930 */
931
932 zmw_enter_critical_section(dev);
933
934 //wd->aggQPool[qnum]->clearFlag = wd->aggQPool[qnum]->deleteFlag =1;
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 * this (aid, ac) not yet aggregated
947 * queue not found
948 */
949
950 //if (arrivalrate > ZM_AGG_HIGH_THRESHOLD)
951 if (1)
952 {
953 /*
954 * arrivalrate high enough to get a new agg queue
955 */
956
957 tid_tx = zfAggTxNewQueue(dev, aid, tid, buf);
958
959 //zm_msg1_agg(ZM_LV_0, "get new AggQueue qnum = ", tid_tx->);
960
961 if (tid_tx)
962 {
963 /*
964 * got a new aggregate queue
965 */
966
967 //zmw_enter_critical_section(dev);
968
969 //wd->aggSta[aid].aggFlag[ac] = 1;
970
971 //zmw_leave_critical_section(dev);
972
973 /*
974 * add ADDBA functions here
975 * return ZM_ERR_TX_BUFFER_UNAVAILABLE;
976 */
977
978
979 //zfAggSendAddbaRequest(dev, tid_tx->dst, tid_tx->ac, tid_tx->tid);
980 //zmw_enter_critical_section(dev);
981
982 //wd->aggSta[aid].aggFlag[ac] = 0;
983
984 //zmw_leave_critical_section(dev);
985
986 return zfAggTxEnqueue(dev, buf, aid, tid_tx);
987
988 }
989 else
990 {
991 /*
992 * just can't get a new aggregate queue
993 */
994
995 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
996 }
997 }
998 else
999 {
1000 /*
1001 * arrival rate is not high enough to get a new agg queue
1002 */
1003
1004 return ZM_ERR_TX_BUFFER_UNAVAILABLE;
1005 }
1006 }
1007
1008
1009
1010 }
1011
1012
1013 /************************************************************************/
1014 /* */
1015 /* FUNCTION DESCRIPTION zfAggTxReadyCount */
1016 /* return counter of ready to aggregate queues. */
1017 /* take (dev, ac) as input, only calculate the ready to aggregate */
1018 /* queues of one particular ac. */
1019 /* */
1020 /* INPUTS */
1021 /* dev : device pointer */
1022 /* ac : access category */
1023 /* */
1024 /* OUTPUTS */
1025 /* counter of ready to aggregate queues */
1026 /* */
1027 /* AUTHOR */
1028 /* Honda Atheros Communications, INC. 2006.12 */
1029 /* */
1030 /************************************************************************/
1031 u16_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 /* FUNCTION DESCRIPTION zfAggTxPartial */
1057 /* return the number that Vtxq has to send. */
1058 /* take (dev, ac, readycount) as input, calculate the ratio of */
1059 /* Vtxq length to (Vtxq length + readycount) of a particular ac, */
1060 /* and returns the Vtxq length * the ratio */
1061 /* */
1062 /* INPUTS */
1063 /* dev : device pointer */
1064 /* ac : access category */
1065 /* readycount: the number of ready to aggregate queues of this ac */
1066 /* */
1067 /* OUTPUTS */
1068 /* Vtxq length * ratio */
1069 /* */
1070 /* AUTHOR */
1071 /* Honda Atheros Communications, INC. 2006.12 */
1072 /* */
1073 /************************************************************************/
1074 u16_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 /* FUNCTION DESCRIPTION zfAggTxSend */
1109 /* return sentcount */
1110 /* take (dev, ac, n) as input, n is the number of scheduled agg */
1111 /* queues to be sent of the particular ac. */
1112 /* */
1113 /* INPUTS */
1114 /* dev : device pointer */
1115 /* ac : access category */
1116 /* n : the number of scheduled aggregation queues to be sent */
1117 /* */
1118 /* OUTPUTS */
1119 /* sentcount */
1120 /* */
1121 /* AUTHOR */
1122 /* Honda Atheros Communications, INC. 2006.12 */
1123 /* */
1124 /************************************************************************/
1125 u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx)
1126 {
1127 //u16_t qnum;
1128 //u16_t qlen;
1129 u16_t j;
1130 //u16_t sentcount = 0;
1131 zbuf_t* buf;
1132 struct aggControl aggControl;
1133 u16_t aggLen;
1134 //zbuf_t* newBuf;
1135 //u16_t bufLen;
1136 //TID_BAW tid_baw = NULL;
1137 //struct bufInfo *buf_info;
1138
1139 zmw_get_wlan_dev(dev);
1140
1141 zmw_declare_for_critical_section();
1142
1143 //while (tid_tx->size > 0)
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 * why there have to be 2 free Txd?
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 //DESTQ.delete(dev, 0, tid_tx, NULL);
1163 }
1164
1165 return 1;
1166 }
1167 /*
1168 * Free Txd queue is big enough to put aggregation
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 //struct aggTally *agg_tal;
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 //wd->aggState = 0;
1200
1201 }
1202 else
1203 {
1204 aggControl.ampduIndication = ZM_AGG_MIDDLE_MPDU;
1205 /* the packet is delayed more than 500 ms, drop it */
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 * this aggregation queue is empty
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 //zm_acquire_agg_spin_lock(Adapter);
1247 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail);
1248 //zm_release_agg_spin_lock(Adapter);
1249
1250 if (tid_tx->size == 0) {
1251 //DESTQ.delete(dev, 0, tid_tx, NULL);
1252 }
1253
1254
1255
1256 //zfAggInvokeBar(dev, tid_tx);
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 /* FUNCTION DESCRIPTION zfAggTxGetReadyQueue */
1269 /* return the number of the aggregation queue */
1270 /* take (dev, ac) as input, find the agg queue with smallest */
1271 /* arrival time (waited longest) among those ready or clearFlag */
1272 /* set queues. */
1273 /* */
1274 /* INPUTS */
1275 /* dev : device pointer */
1276 /* ac : access category */
1277 /* */
1278 /* OUTPUTS */
1279 /* aggregation queue number */
1280 /* */
1281 /* AUTHOR */
1282 /* Honda Atheros Communications, INC. 2006.12 */
1283 /* */
1284 /************************************************************************/
1285 TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac)
1286 {
1287 //u16_t qnum = ZM_AGG_POOL_SIZE;
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 /* FUNCTION DESCRIPTION zfAggTxGetVtxq */
1322 /* return an MSDU */
1323 /* take (dev, qnum) as input, return an MSDU out of the agg queue. */
1324 /* */
1325 /* INPUTS */
1326 /* dev : device pointer */
1327 /* qnum: queue number */
1328 /* */
1329 /* OUTPUTS */
1330 /* a MSDU */
1331 /* */
1332 /* AUTHOR */
1333 /* Honda Atheros Communications, INC. 2006.12 */
1334 /* */
1335 /************************************************************************/
1336 zbuf_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 //tid_tx->aggTail = tid_tx->aggHead = tid_tx->size = 0;
1354 //zm_msg1_agg(ZM_LV_0, "GetVtxq buf == NULL, tid_tx->size=", tid_tx->size);
1355 }
1356 zmw_leave_critical_section(dev);
1357 }
1358 else
1359 {
1360 /*
1361 * queue is empty
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 /* FUNCTION DESCRIPTION zfAggTxDeleteQueue */
1376 /* return ZM_SUCCESS (can't fail) */
1377 /* take (dev, qnum) as input, reset (delete) this aggregate queue, */
1378 /* this queue is virtually returned to the aggregate queue pool. */
1379 /* */
1380 /* INPUTS */
1381 /* dev : device pointer */
1382 /* qnum: queue number */
1383 /* */
1384 /* OUTPUTS */
1385 /* ZM_SUCCESS */
1386 /* */
1387 /* AUTHOR */
1388 /* Honda Atheros Communications, INC. 2006.12 */
1389 /* */
1390 /************************************************************************/
1391 u16_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 //disable BAW
1427 void 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 //zmw_declare_for_critical_section();
1435 tid_baw = BAW->getQ(dev, baw_seq);
1436 //tid_baw = NULL;
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 //wd->zfcbSetBawQ(dev, buf, 0);
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
1460 void zfBawInit(zdev_t* dev) {
1461 TID_BAW tid_baw;
1462 u16_t i,j;
1463 zmw_get_wlan_dev(dev);
1464 //zmw_declare_for_critical_section();
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
1486 TID_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 //zmw_declare_for_critical_section();
1492
1493 /*
1494 for (i=0; i<ZM_BAW_POOL_SIZE; i++){
1495 tid_baw = &BAW->tid_baw[i];
1496 if (FALSE == tid_baw->enabled)
1497 break;
1498 }
1499 */
1500
1501 tid_baw = &BAW->tid_baw[BAW->delPoint];
1502 i = BAW->delPoint;
1503 //if (ZM_BAW_POOL_SIZE == i) {
1504 //return NULL;
1505 // u8_t temp = BAW->delPoint;
1506 // tid_baw = &BAW->tid_baw[BAW->delPoint];
1507 // BAW->disable(dev, tid_baw);
1508 // BAW->delPoint = (BAW->delPoint < (ZM_BAW_POOL_SIZE - 1))? (BAW->delPoint + 1): 0;
1509 // temp = BAW->delPoint;
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
1523 u16_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 //TID_BAW tid_baw;
1525 //u16_t bufLen;
1526
1527 //zmw_get_wlan_dev(dev);
1528 //zmw_declare_for_critical_section();
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 //wd->zfcbSetBawQ(dev, buf, 1);
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 //tid_baw->frame[tid_baw->head].data = pBuf->data;
1547 tid_baw->head++;
1548 tid_baw->size++;
1549 }
1550 else {
1551 //wd->zfcbSetBawQ(dev, buf, 0);
1552 zfwBufFree(dev, buf, ZM_SUCCESS);
1553 return FALSE;
1554 }
1555 return TRUE;
1556 }
1557
1558 struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw) {
1559 //TID_BAW tid_baw;
1560 //zbuf_t* buf;
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 //pBuf->data = pBuf->buffer;
1574 //wd->zfcbRestoreBufData(dev, buf);
1575 tid_baw->frame[index].buf = NULL;
1576
1577 return buf_info;
1578 }
1579
1580 void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq) {
1581 //TID_BAW tid_baw;
1582
1583 //zmw_get_wlan_dev(dev);
1584 //zmw_declare_for_critical_section();
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
1591 void zfBawDisable(zdev_t* dev, TID_BAW tid_baw) {
1592 //TID_BAW tid_baw;
1593 u16_t i;
1594
1595 //zmw_get_wlan_dev(dev);
1596 //zmw_declare_for_critical_section();
1597 for (i=0; i<ZM_VTXQ_SIZE; i++) {
1598 if (tid_baw->frame[i].buf) {
1599
1600 //wd->zfcbSetBawQ(dev, tid_baw->frame[i].buf, 0);
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
1609 TID_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 //zmw_declare_for_critical_section();
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 //disable BAW
1631 #endif
1632
1633 u16_t zfAggTallyReset(zdev_t* dev)
1634 {
1635 struct aggTally* agg_tal;
1636
1637 zmw_get_wlan_dev(dev);
1638
1639 //zmw_declare_for_critical_section();
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 /* FUNCTION DESCRIPTION zfAggScanAndClear */
1658 /* If the packets in a queue have waited for too long, clear and */
1659 /* delete this aggregation queue. */
1660 /* */
1661 /* INPUTS */
1662 /* dev : device pointer */
1663 /* time : current time */
1664 /* */
1665 /* OUTPUTS */
1666 /* ZM_SUCCESS */
1667 /* */
1668 /* AUTHOR */
1669 /* Honda Atheros Communications, INC. 2006.12 */
1670 /* */
1671 /************************************************************************/
1672 u16_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 //u16_t aid, ac;
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 //zm_msg1_agg(ZM_LV_0, "clear queue tick =", tick);
1713 //zm_msg1_agg(ZM_LV_0, "clear queue arrival =", arrivalTime);
1714
1715
1716 //zmw_leave_critical_section(dev);
1717 //zfAggTxScheduler(dev);
1718 //zmw_enter_critical_section(dev);
1719
1720 }
1721
1722 if (tid_tx->size == 0)
1723 {
1724 /*
1725 * queue empty
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
1753 u16_t zfAggPrintTally(zdev_t* dev)
1754 {
1755 struct aggTally* agg_tal;
1756
1757 zmw_get_wlan_dev(dev);
1758
1759 //zmw_declare_for_critical_section();
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
1799 u16_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
1833 struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf)
1834 {
1835 u16_t dst0, src[3], aid;
1836 u16_t offset = 0;
1837 u16_t seq_no;
1838 u16_t frameType;
1839 u16_t frameCtrl;
1840 u16_t frameSubtype;
1841 //struct aggSta *agg_sta;
1842 #if ZM_AGG_FPGA_REORDERING
1843 struct agg_tid_rx *tid_rx;
1844 #endif
1845 zmw_get_wlan_dev(dev);
1846
1847 //zmw_declare_for_critical_section();
1848 seq_no = zmw_rx_buf_readh(dev, buf, 22) >> 4;
1849 //DbgPrint("Rx seq=%d\n", seq_no);
1850 if (wd->sta.EnableHT == 0)
1851 {
1852 return NULL;
1853 }
1854
1855 frameCtrl = zmw_rx_buf_readb(dev, buf, 0);
1856 frameType = frameCtrl & 0xf;
1857 frameSubtype = frameCtrl & 0xf0;
1858
1859
1860 if (frameType != ZM_WLAN_DATA_FRAME) //non-Qos Data? (frameSubtype&0x80)
1861 {
1862 return NULL;
1863 }
1864 #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION
1865 {
1866 u32_t tcp_seq;
1867
1868 tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24;
1869 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16;
1870 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8;
1871 tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39);
1872 ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq);
1873 }
1874 #endif
1875
1876 dst0 = zmw_rx_buf_readh(dev, buf, offset+4);
1877
1878 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
1879 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
1880 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
1881
1882 #if ZM_AGG_FPGA_DEBUG
1883 aid = 0;
1884 #else
1885 aid = zfApFindSta(dev, src);
1886 #endif
1887
1888 //agg_sta = &wd->aggSta[aid];
1889 //zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
1890 //ac = zcUpToAc[up&0x7] & 0x3;
1891
1892 /*
1893 * Filter unicast frame only, aid == 0 is for debug only
1894 */
1895 if ((dst0 & 0x1) == 0 && aid == 0)
1896 {
1897 #if ZM_AGG_FPGA_REORDERING
1898 tid_rx = zfAggRxGetQueue(dev, buf) ;
1899 if(!tid_rx)
1900 return NULL;
1901 else
1902 {
1903 //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE)
1904 return tid_rx;
1905 }
1906 #else
1907 return NULL;
1908 #endif
1909 }
1910
1911 return NULL;
1912 }
1913
1914 u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx)
1915 {
1916 u16_t seq_no;
1917 s16_t index;
1918 u16_t offset = 0;
1919 zbuf_t* pbuf;
1920 u8_t frameSubType;
1921
1922 zmw_get_wlan_dev(dev);
1923
1924 zmw_declare_for_critical_section();
1925
1926 ZM_BUFFER_TRACE(dev, buf)
1927
1928 ZM_PERFORMANCE_RX_REORDER(dev);
1929
1930 seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1931
1932 index = seq_no - tid_rx->seq_start;
1933 /*
1934 * for debug
1935 */
1936
1937 /* zm_msg2_agg(ZM_LV_0, "queue seq = ", seq_no);
1938 * DbgPrint("%s:%s%lxh %s%lxh\n", __func__, "queue seq=", seq_no,
1939 * "; seq_start=", tid_rx->seq_start);
1940 */
1941
1942 //DbgPrint("seq_no=%d, seq_start=%d\n", seq_no, tid_rx->seq_start);
1943
1944 /* In some APs, we found that it might transmit NULL data whose sequence number
1945 is out or order. In order to avoid this problem, we ignore these NULL data.
1946 */
1947
1948 frameSubType = (zmw_rx_buf_readh(dev, buf, 0) & 0xF0) >> 4;
1949
1950 /* If this is a NULL data instead of Qos NULL data */
1951 if ((frameSubType & 0x0C) == 0x04)
1952 {
1953 s16_t seq_diff;
1954
1955 seq_diff = (seq_no > tid_rx->seq_start) ?
1956 seq_no - tid_rx->seq_start : tid_rx->seq_start - seq_no;
1957
1958 if (seq_diff > ZM_AGG_BAW_SIZE)
1959 {
1960 zm_debug_msg0("Free Rx NULL data in zfAggRx");
1961
1962 /* Free Rx buffer */
1963 zfwBufFree(dev, buf, 0);
1964 return ZM_ERR_OUT_OF_ORDER_NULL_DATA;
1965 }
1966 }
1967
1968 /*
1969 * sequence number wrap at 4k
1970 */
1971 if (tid_rx->seq_start > seq_no)
1972 {
1973 //index += 4096;
1974
1975 zmw_enter_critical_section(dev);
1976 if (tid_rx->seq_start >= 4096) {
1977 tid_rx->seq_start = 0;
1978 }
1979 zmw_leave_critical_section(dev);
1980
1981 }
1982
1983 if (tid_rx->seq_start == seq_no) {
1984 zmw_enter_critical_section(dev);
1985 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) > 0) {
1986 //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
1987 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
1988 }
1989 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
1990 zmw_leave_critical_section(dev);
1991
1992 ZM_PERFORMANCE_RX_SEQ(dev, buf);
1993
1994 if (wd->zfcbRecv80211 != NULL) {
1995 //seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
1996 //DbgPrint("Recv indicate seq=%d\n", seq_no);
1997 //DbgPrint("1. seq=%d\n", seq_no);
1998
1999 wd->zfcbRecv80211(dev, buf, addInfo);
2000 }
2001 else {
2002 zfiRecv80211(dev, buf, addInfo);
2003 }
2004 }
2005 else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo))
2006 {
2007 /*
2008 * duplicated packet
2009 */
2010 return 1;
2011 }
2012
2013 while (tid_rx->baw_head != tid_rx->baw_tail) {// && tid_rx->frame[tid_rx->baw_tail].buf)
2014 u16_t tailIndex;
2015
2016 zmw_enter_critical_section(dev);
2017
2018 tailIndex = tid_rx->baw_tail;
2019 pbuf = tid_rx->frame[tailIndex].buf;
2020 tid_rx->frame[tailIndex].buf = 0;
2021 if (!pbuf)
2022 {
2023 zmw_leave_critical_section(dev);
2024 break;
2025 }
2026
2027 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2028 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2029
2030
2031 //if(pbuf && tid_rx->baw_size > 0)
2032 // tid_rx->baw_size--;
2033
2034 zmw_leave_critical_section(dev);
2035
2036 ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2037
2038 if (wd->zfcbRecv80211 != NULL)
2039 {
2040 //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2041 //DbgPrint("Recv indicate seq=%d\n", seq_no);
2042 //DbgPrint("1. seq=%d\n", seq_no);
2043 wd->zfcbRecv80211(dev, pbuf, addInfo);
2044 }
2045 else
2046 {
2047 //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4;
2048 //DbgPrint("Recv indicate seq=%d\n", seq_no);
2049 zfiRecv80211(dev, pbuf, addInfo);
2050 }
2051 }
2052
2053 return 1;
2054 }
2055
2056 struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf)
2057 {
2058 u16_t src[3];
2059 u16_t aid, ac, i;
2060 u16_t offset = 0;
2061 struct agg_tid_rx *tid_rx = NULL;
2062
2063 zmw_get_wlan_dev(dev);
2064
2065 //zmw_declare_for_critical_section();
2066
2067 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
2068 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
2069 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
2070 aid = zfApFindSta(dev, src);
2071
2072 ac = (zmw_rx_buf_readh(dev, buf, 24) & 0xF);
2073
2074 // mark by spin lock debug
2075 //zmw_enter_critical_section(dev);
2076
2077 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
2078 {
2079 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
2080 {
2081 tid_rx = wd->tid_rx[i];
2082 break;
2083 }
2084 }
2085
2086 // mark by spin lock debug
2087 //zmw_leave_critical_section(dev);
2088 return tid_rx;
2089 }
2090
2091
2092 u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo)
2093 {
2094 u16_t seq_no, offset = 0;
2095 u16_t q_index;
2096 s16_t index;
2097 u8_t bdropframe = 0;
2098
2099 zmw_get_wlan_dev(dev);
2100
2101 zmw_declare_for_critical_section();
2102
2103 ZM_BUFFER_TRACE(dev, buf)
2104
2105 seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4;
2106 index = seq_no - tid_rx->seq_start;
2107
2108 /*
2109 * sequence number wrap at 4k
2110 * -1000: check for duplicate past packet
2111 */
2112 bdropframe = 0;
2113 if (tid_rx->seq_start > seq_no) {
2114 if ((tid_rx->seq_start > 3967) && (seq_no < 128)) {
2115 index += 4096;
2116 } else if (tid_rx->seq_start - seq_no > 70) {
2117 zmw_enter_critical_section(dev);
2118 tid_rx->sq_behind_count++;
2119 if (tid_rx->sq_behind_count > 3) {
2120 tid_rx->sq_behind_count = 0;
2121 } else {
2122 bdropframe = 1;
2123 }
2124 zmw_leave_critical_section(dev);
2125 } else {
2126 bdropframe = 1;
2127 }
2128 } else {
2129 if (seq_no - tid_rx->seq_start > 70) {
2130 zmw_enter_critical_section(dev);
2131 tid_rx->sq_exceed_count++;
2132 if (tid_rx->sq_exceed_count > 3) {
2133 tid_rx->sq_exceed_count = 0;
2134 } else {
2135 bdropframe = 1;
2136 }
2137 zmw_leave_critical_section(dev);
2138 }
2139 }
2140
2141 if (bdropframe == 1) {
2142 /*if (wd->zfcbRecv80211 != NULL) {
2143 wd->zfcbRecv80211(dev, buf, addInfo);
2144 }
2145 else {
2146 zfiRecv80211(dev, buf, addInfo);
2147 }*/
2148
2149 ZM_PERFORMANCE_FREE(dev, buf);
2150
2151 zfwBufFree(dev, buf, 0);
2152 /*zfAggRxFlush(dev, seq_no, tid_rx);
2153 tid_rx->seq_start = seq_no;
2154 index = seq_no - tid_rx->seq_start;
2155 */
2156
2157 //DbgPrint("Free an old packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2158
2159 /*
2160 * duplicate past packet
2161 * happens only in simulated aggregation environment
2162 */
2163 return 0;
2164 } else {
2165 zmw_enter_critical_section(dev);
2166 if (tid_rx->sq_exceed_count > 0){
2167 tid_rx->sq_exceed_count--;
2168 }
2169
2170 if (tid_rx->sq_behind_count > 0) {
2171 tid_rx->sq_behind_count--;
2172 }
2173 zmw_leave_critical_section(dev);
2174 }
2175
2176 if (index < 0) {
2177 zfAggRxFlush(dev, seq_no, tid_rx);
2178 tid_rx->seq_start = seq_no;
2179 index = 0;
2180 }
2181
2182 //if (index >= (ZM_AGG_BAW_SIZE - 1))
2183 if (index >= (ZM_AGG_BAW_MASK))
2184 {
2185 /*
2186 * queue full
2187 */
2188 //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2189 zfAggRxFlush(dev, seq_no, tid_rx);
2190 //tid_rx->seq_start = seq_no;
2191 index = seq_no - tid_rx->seq_start;
2192 if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2193 {
2194 //index = seq_no - tid_rx->seq_start;
2195 index += 4096;
2196 }
2197 //index = seq_no - tid_rx->seq_start;
2198 while (index >= (ZM_AGG_BAW_MASK)) {
2199 //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2200 tid_rx->seq_start = (tid_rx->seq_start + ZM_AGG_BAW_MASK) & (4096 - 1);
2201 index = seq_no - tid_rx->seq_start;
2202 if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no)
2203 {
2204 index += 4096;
2205 }
2206 }
2207 }
2208
2209
2210 q_index = (tid_rx->baw_tail + index) & ZM_AGG_BAW_MASK;
2211 if (tid_rx->frame[q_index].buf && (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) >
2212 (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK)))
2213 {
2214
2215 ZM_PERFORMANCE_DUP(dev, tid_rx->frame[q_index].buf, buf);
2216 zfwBufFree(dev, buf, 0);
2217 //DbgPrint("Free a duplicate packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no);
2218 //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail);
2219 /*
2220 * duplicate packet
2221 */
2222 return 0;
2223 }
2224
2225 zmw_enter_critical_section(dev);
2226 if(tid_rx->frame[q_index].buf) {
2227 zfwBufFree(dev, tid_rx->frame[q_index].buf, 0);
2228 tid_rx->frame[q_index].buf = 0;
2229 }
2230
2231 tid_rx->frame[q_index].buf = buf;
2232 tid_rx->frame[q_index].arrivalTime = zm_agg_GetTime();
2233 zfwMemoryCopy((void*)&tid_rx->frame[q_index].addInfo, (void*)addInfo, sizeof(struct zsAdditionInfo));
2234
2235 /*
2236 * for debug simulated aggregation only,
2237 * should be done in rx of ADDBA Request
2238 */
2239 //tid_rx->addInfo = addInfo;
2240
2241
2242 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= index)
2243 {
2244 //tid_rx->baw_size = index + 1;
2245 if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <=
2246 //((q_index + 1) & ZM_AGG_BAW_MASK))
2247 (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK))//tid_rx->baw_size )
2248 tid_rx->baw_head = (q_index + 1) & ZM_AGG_BAW_MASK;
2249 }
2250 zmw_leave_critical_section(dev);
2251
2252 /*
2253 * success
2254 */
2255 //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start);
2256 return 1;
2257 }
2258
2259 u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx)
2260 {
2261 zbuf_t* pbuf;
2262 u16_t seq;
2263 struct zsAdditionInfo addInfo;
2264 zmw_get_wlan_dev(dev);
2265 zmw_declare_for_critical_section();
2266
2267 ZM_PERFORMANCE_RX_FLUSH(dev);
2268
2269 while (1)
2270 {
2271 zmw_enter_critical_section(dev);
2272 if (tid_rx->baw_tail == tid_rx->baw_head) {
2273 zmw_leave_critical_section(dev);
2274 break;
2275 }
2276
2277 pbuf = tid_rx->frame[tid_rx->baw_tail].buf;
2278 zfwMemoryCopy((void*)&addInfo, (void*)&tid_rx->frame[tid_rx->baw_tail].addInfo, sizeof(struct zsAdditionInfo));
2279 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2280 //if(pbuf && tid_rx->baw_size > 0) tid_rx->baw_size--;
2281 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2282 tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1);
2283 zmw_leave_critical_section(dev);
2284
2285 if (pbuf)
2286 {
2287
2288 ZM_PERFORMANCE_RX_SEQ(dev, pbuf);
2289
2290 if (wd->zfcbRecv80211 != NULL)
2291 {
2292 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2293 //DbgPrint("Recv indicate seq=%d\n", seq);
2294 //DbgPrint("2. seq=%d\n", seq);
2295 wd->zfcbRecv80211(dev, pbuf, &addInfo);
2296 }
2297 else
2298 {
2299 seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4;
2300 //DbgPrint("Recv indicate seq=%d\n", seq);
2301 zfiRecv80211(dev, pbuf, &addInfo);
2302 }
2303 }
2304 }
2305
2306 zmw_enter_critical_section(dev);
2307 tid_rx->baw_head = tid_rx->baw_tail = 0;
2308 zmw_leave_critical_section(dev);
2309 return 1;
2310 }
2311
2312
2313
2314 /************************************************************************/
2315 /* */
2316 /* FUNCTION DESCRIPTION zfAggRxFreeBuf */
2317 /* Frees all queued packets in buffer when the driver is down. */
2318 /* The zfFreeResource() will check if the buffer is all freed. */
2319 /* */
2320 /* INPUTS */
2321 /* dev : device pointer */
2322 /* */
2323 /* OUTPUTS */
2324 /* ZM_SUCCESS */
2325 /* */
2326 /* AUTHOR */
2327 /* Honda Atheros Communications, INC. 2006.12 */
2328 /* */
2329 /************************************************************************/
2330 u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy)
2331 {
2332 u16_t i;
2333 zbuf_t* buf;
2334 struct agg_tid_rx *tid_rx;
2335
2336 TID_TX tid_tx;
2337 //struct bufInfo *buf_info;
2338
2339 zmw_get_wlan_dev(dev);
2340 zmw_declare_for_critical_section();
2341
2342 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
2343 {
2344 u16_t j;
2345
2346 tid_rx = wd->tid_rx[i];
2347
2348 for(j=0; j <= ZM_AGG_BAW_SIZE; j++)
2349 {
2350 zmw_enter_critical_section(dev);
2351 buf = tid_rx->frame[j].buf;
2352 tid_rx->frame[j].buf = 0;
2353 zmw_leave_critical_section(dev);
2354
2355 if (buf)
2356 {
2357 zfwBufFree(dev, buf, 0);
2358 }
2359 }
2360
2361 #if 0
2362 if ( tid_rx->baw_head != tid_rx->baw_tail )
2363 {
2364 while (tid_rx->baw_head != tid_rx->baw_tail)
2365 {
2366 buf = tid_rx->frame[tid_rx->baw_tail].buf;
2367 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2368 if (buf)
2369 {
2370 zfwBufFree(dev, buf, 0);
2371
2372 zmw_enter_critical_section(dev);
2373 tid_rx->frame[tid_rx->baw_tail].buf = 0;
2374 zmw_leave_critical_section(dev);
2375 }
2376 zmw_enter_critical_section(dev);
2377 //if (tid_rx->baw_size > 0)tid_rx->baw_size--;
2378 tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK;
2379 tid_rx->seq_start++;
2380 zmw_leave_critical_section(dev);
2381 }
2382 }
2383 #endif
2384
2385 zmw_enter_critical_section(dev);
2386 tid_rx->seq_start = 0;
2387 tid_rx->baw_head = tid_rx->baw_tail = 0;
2388 tid_rx->aid = ZM_MAX_STA_SUPPORT;
2389 zmw_leave_critical_section(dev);
2390
2391 #ifdef ZM_ENABLE_AGGREGATION
2392 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2393 if (tid_baw->enabled) {
2394 zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i);
2395 BAW->disable(dev, tid_baw);
2396 }
2397 #endif
2398 #endif
2399 if (1 == wd->aggQPool[i]->aggQEnabled) {
2400 tid_tx = wd->aggQPool[i];
2401 buf = zfAggTxGetVtxq(dev, tid_tx);
2402 while (buf) {
2403 zfwBufFree(dev, buf, 0);
2404 buf = zfAggTxGetVtxq(dev, tid_tx);
2405 }
2406 }
2407
2408 if(destroy) {
2409 zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue));
2410 zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx));
2411 }
2412 }
2413 #ifdef ZM_ENABLE_AGGREGATION
2414 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2415 if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler));
2416 #endif
2417 #endif
2418 return ZM_SUCCESS;
2419 }
2420
2421
2422 void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) {
2423 u16_t start_seq, len;
2424 u8_t i, bitmap[8];
2425 len = zfwBufGetSize(dev, buf);
2426 start_seq = zmw_rx_buf_readh(dev, buf, len-2);
2427 DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4);
2428 /* todo: set the bitmap by reordering buffer! */
2429 for (i=0; i<8; i++) bitmap[i]=0;
2430 zfSendBA(dev, start_seq, bitmap);
2431 }
2432
2433 #ifdef ZM_ENABLE_AGGREGATION
2434 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW
2435 void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) {
2436 u16_t removeLen;
2437 u16_t err;
2438
2439 zmw_get_wlan_dev(dev);
2440 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2441 tid_tx->bar_ssn = buf_info->baw_header->header[15];
2442 aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4;
2443 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2444 }
2445 buf_info->baw_header->header[4] |= (1 << 11);
2446 if (aggControl && aggControl->aggEnabled) {
2447 //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1))
2448 //{
2449 //if (((buf_info->baw_header->header[2] & 0x3) == 2))
2450 //{
2451 /* Enable aggregation */
2452 buf_info->baw_header->header[1] |= 0x20;
2453 if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) {
2454 buf_info->baw_header->header[1] |= 0x4000;
2455 }
2456 else {
2457 buf_info->baw_header->header[1] &= ~0x4000;
2458 //zm_debug_msg0("ZM_AGG_LAST_MPDU");
2459 }
2460 //}
2461 //else {
2462 // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3)
2463 // aggControl->aggEnabled = 0;
2464 //}
2465 //}
2466 //else {
2467 // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation);
2468 // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1));
2469 // aggControl->aggEnabled = 0;
2470 //}
2471 }
2472
2473 /*if (aggControl->tid_baw) {
2474 struct baw_header_r header_r;
2475
2476 header_r.header = buf_info->baw_header->header;
2477 header_r.mic = buf_info->baw_header->mic;
2478 header_r.snap = buf_info->baw_header->snap;
2479 header_r.headerLen = buf_info->baw_header->headerLen;
2480 header_r.micLen = buf_info->baw_header->micLen;
2481 header_r.snapLen = buf_info->baw_header->snapLen;
2482 header_r.removeLen = buf_info->baw_header->removeLen;
2483 header_r.keyIdx = buf_info->baw_header->keyIdx;
2484
2485 BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r);
2486 }*/
2487
2488 err = zfHpSend(dev,
2489 buf_info->baw_header->header,
2490 buf_info->baw_header->headerLen,
2491 buf_info->baw_header->snap,
2492 buf_info->baw_header->snapLen,
2493 buf_info->baw_header->mic,
2494 buf_info->baw_header->micLen,
2495 buf_info->buf,
2496 buf_info->baw_header->removeLen,
2497 ZM_EXTERNAL_ALLOC_BUF,
2498 (u8_t)tid_tx->ac,
2499 buf_info->baw_header->keyIdx);
2500 if (err != ZM_SUCCESS)
2501 {
2502 goto zlError;
2503 }
2504
2505 return;
2506
2507 zlError:
2508 zfwBufFree(dev, buf_info->buf, 0);
2509 return;
2510
2511 }
2512 #endif //disable BAW
2513 #endif
2514 /************************************************************************/
2515 /* */
2516 /* FUNCTION DESCRIPTION zfAggTxSendEth */
2517 /* Called to transmit Ethernet frame from upper elayer. */
2518 /* */
2519 /* INPUTS */
2520 /* dev : device pointer */
2521 /* buf : buffer pointer */
2522 /* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */
2523 /* */
2524 /* OUTPUTS */
2525 /* error code */
2526 /* */
2527 /* AUTHOR */
2528 /* Stephen, Honda Atheros Communications, Inc. 2006.12 */
2529 /* */
2530 /************************************************************************/
2531 u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx)
2532 {
2533 u16_t err;
2534 //u16_t addrTblSize;
2535 //struct zsAddrTbl addrTbl;
2536 u16_t removeLen;
2537 u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */
2538 u16_t headerLen;
2539 u16_t mic[8/2];
2540 u16_t micLen;
2541 u16_t snap[8/2];
2542 u16_t snapLen;
2543 u16_t fragLen;
2544 u16_t frameLen;
2545 u16_t fragNum;
2546 struct zsFrag frag;
2547 u16_t i, id;
2548 u16_t da[3];
2549 u16_t sa[3];
2550 u8_t up;
2551 u8_t qosType, keyIdx = 0;
2552 u16_t fragOff;
2553
2554 zmw_get_wlan_dev(dev);
2555
2556 zmw_declare_for_critical_section();
2557
2558 zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port);
2559
2560 /* Get IP TOS for QoS AC and IP frag offset */
2561 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
2562
2563 #ifdef ZM_ENABLE_NATIVE_WIFI
2564 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
2565 {
2566 /* DA */
2567 da[0] = zmw_tx_buf_readh(dev, buf, 16);
2568 da[1] = zmw_tx_buf_readh(dev, buf, 18);
2569 da[2] = zmw_tx_buf_readh(dev, buf, 20);
2570 /* SA */
2571 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2572 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2573 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2574 }
2575 else if ( wd->wlanMode == ZM_MODE_IBSS )
2576 {
2577 /* DA */
2578 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2579 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2580 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2581 /* SA */
2582 sa[0] = zmw_tx_buf_readh(dev, buf, 10);
2583 sa[1] = zmw_tx_buf_readh(dev, buf, 12);
2584 sa[2] = zmw_tx_buf_readh(dev, buf, 14);
2585 }
2586 else if ( wd->wlanMode == ZM_MODE_AP )
2587 {
2588 /* DA */
2589 da[0] = zmw_tx_buf_readh(dev, buf, 4);
2590 da[1] = zmw_tx_buf_readh(dev, buf, 6);
2591 da[2] = zmw_tx_buf_readh(dev, buf, 8);
2592 /* SA */
2593 sa[0] = zmw_tx_buf_readh(dev, buf, 16);
2594 sa[1] = zmw_tx_buf_readh(dev, buf, 18);
2595 sa[2] = zmw_tx_buf_readh(dev, buf, 20);
2596 }
2597 else
2598 {
2599 //
2600 }
2601 #else
2602 /* DA */
2603 da[0] = zmw_tx_buf_readh(dev, buf, 0);
2604 da[1] = zmw_tx_buf_readh(dev, buf, 2);
2605 da[2] = zmw_tx_buf_readh(dev, buf, 4);
2606 /* SA */
2607 sa[0] = zmw_tx_buf_readh(dev, buf, 6);
2608 sa[1] = zmw_tx_buf_readh(dev, buf, 8);
2609 sa[2] = zmw_tx_buf_readh(dev, buf, 10);
2610 #endif
2611 //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m)
2612 if (wd->wlanMode == ZM_MODE_AP)
2613 {
2614 keyIdx = wd->ap.bcHalKeyIdx[port];
2615 id = zfApFindSta(dev, da);
2616 if (id != 0xffff)
2617 {
2618 switch (wd->ap.staTable[id].encryMode)
2619 {
2620 case ZM_AES:
2621 case ZM_TKIP:
2622 #ifdef ZM_ENABLE_CENC
2623 case ZM_CENC:
2624 #endif //ZM_ENABLE_CENC
2625 keyIdx = wd->ap.staTable[id].keyIdx;
2626 break;
2627 }
2628 }
2629 }
2630 else
2631 {
2632 switch (wd->sta.encryMode)
2633 {
2634 case ZM_WEP64:
2635 case ZM_WEP128:
2636 case ZM_WEP256:
2637 keyIdx = wd->sta.keyId;
2638 break;
2639 case ZM_AES:
2640 case ZM_TKIP:
2641 if ((da[0]& 0x1))
2642 keyIdx = 5;
2643 else
2644 keyIdx = 4;
2645 break;
2646 #ifdef ZM_ENABLE_CENC
2647 case ZM_CENC:
2648 keyIdx = wd->sta.cencKeyId;
2649 break;
2650 #endif //ZM_ENABLE_CENC
2651 }
2652 }
2653
2654 /* Create SNAP */
2655 removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen);
2656 //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff);
2657
2658 fragLen = wd->fragThreshold;
2659 frameLen = zfwBufGetSize(dev, buf);
2660 frameLen -= removeLen;
2661
2662 #if 0
2663 /* Create MIC */
2664 if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&
2665 (wd->sta.encryMode == ZM_TKIP) )
2666 {
2667 if ( frameLen > fragLen )
2668 {
2669 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2670 }
2671 else
2672 {
2673 /* append MIC by HMAC */
2674 micLen = 8;
2675 }
2676 }
2677 else
2678 {
2679 micLen = 0;
2680 }
2681 #else
2682 if ( frameLen > fragLen )
2683 {
2684 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic);
2685 }
2686 else
2687 {
2688 /* append MIC by HMAC */
2689 micLen = 0;
2690 }
2691 #endif
2692
2693 /* Access Category */
2694 if (wd->wlanMode == ZM_MODE_AP)
2695 {
2696 zfApGetStaQosType(dev, da, &qosType);
2697 if (qosType == 0)
2698 {
2699 up = 0;
2700 }
2701 }
2702 else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
2703 {
2704 if (wd->sta.wmeConnected == 0)
2705 {
2706 up = 0;
2707 }
2708 }
2709 else
2710 {
2711 /* TODO : STA QoS control field */
2712 up = 0;
2713 }
2714
2715 /* Assign sequence number */
2716 zmw_enter_critical_section(dev);
2717 frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4);
2718 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) {
2719 tid_tx->bar_ssn = frag.seq[0];
2720
2721 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4);
2722 }
2723 //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0];
2724 zmw_leave_critical_section(dev);
2725
2726
2727 frag.buf[0] = buf;
2728 frag.bufType[0] = bufType;
2729 frag.flag[0] = flag;
2730 fragNum = 1;
2731
2732 for (i=0; i<fragNum; i++)
2733 {
2734 /* Create WLAN header(Control Setting + 802.11 header + IV) */
2735 if (up !=0 ) zm_debug_msg1("up not 0, up=",up);
2736 headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i],
2737 frag.flag[i], snapLen+micLen, removeLen,
2738 port, da, sa, up, &micLen, snap, snapLen,
2739 aggControl);
2740
2741 /* Get buffer DMA address */
2742 //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0)
2743 //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0)
2744 //{
2745 // err = ZM_ERR_BUFFER_DMA_ADDR;
2746 // goto zlError;
2747 //}
2748
2749 /* Flush buffer on cache */
2750 //zfwBufFlush(dev, frag.buf[i]);
2751
2752 #if 0
2753 zm_msg1_tx(ZM_LV_0, "headerLen=", headerLen);
2754 zm_msg1_tx(ZM_LV_0, "snapLen=", snapLen);
2755 zm_msg1_tx(ZM_LV_0, "micLen=", micLen);
2756 zm_msg1_tx(ZM_LV_0, "removeLen=", removeLen);
2757 zm_msg1_tx(ZM_LV_0, "addrTblSize=", addrTblSize);
2758 zm_msg1_tx(ZM_LV_0, "frag.bufType[0]=", frag.bufType[0]);
2759 #endif
2760
2761 fragLen = zfwBufGetSize(dev, frag.buf[i]);
2762 if ((da[0]&0x1) == 0)
2763 {
2764 wd->commTally.txUnicastFrm++;
2765 wd->commTally.txUnicastOctets += (fragLen+snapLen);
2766 }
2767 else if ((da[0]& 0x1))
2768 {
2769 wd->commTally.txBroadcastFrm++;
2770 wd->commTally.txBroadcastOctets += (fragLen+snapLen);
2771 }
2772 else
2773 {
2774 wd->commTally.txMulticastFrm++;
2775 wd->commTally.txMulticastOctets += (fragLen+snapLen);
2776 }
2777 wd->ledStruct.txTraffic++;
2778
2779 #if 0 //Who care this?
2780 if ( (i)&&(i == (fragNum-1)) )
2781 {
2782 wd->trafTally.txDataByteCount -= micLen;
2783 }
2784 #endif
2785
2786 /*if (aggControl->tid_baw && aggControl->aggEnabled) {
2787 struct baw_header_r header_r;
2788
2789 header_r.header = header;
2790 header_r.mic = mic;
2791 header_r.snap = snap;
2792 header_r.headerLen = headerLen;
2793 header_r.micLen = micLen;
2794 header_r.snapLen = snapLen;
2795 header_r.removeLen = removeLen;
2796 header_r.keyIdx = keyIdx;
2797
2798 BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r);
2799 }*/
2800
2801 err = zfHpSend(dev, header, headerLen, snap, snapLen,
2802 mic, micLen, frag.buf[i], removeLen,
2803 frag.bufType[i], zcUpToAc[up&0x7], keyIdx);
2804 if (err != ZM_SUCCESS)
2805 {
2806 goto zlError;
2807 }
2808
2809
2810 continue;
2811
2812 zlError:
2813 if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF)
2814 {
2815 zfwBufFree(dev, frag.buf[i], err);
2816 }
2817 else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF)
2818 {
2819 zfwBufFree(dev, frag.buf[i], 0);
2820 }
2821 else
2822 {
2823 zm_assert(0);
2824 }
2825 } /* for (i=0; i<fragNum; i++) */
2826
2827 return ZM_SUCCESS;
2828 }
2829
2830 /*
2831 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c
2832 */
2833 u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up)
2834 {
2835 zbuf_t* buf;
2836 //u16_t addrTblSize;
2837 //struct zsAddrTbl addrTbl;
2838 //u16_t err;
2839 u16_t offset = 0;
2840 u16_t hlen = 32;
2841 u16_t header[(24+25+1)/2];
2842 u16_t vap = 0;
2843 u16_t i;
2844 u8_t encrypt = 0;
2845
2846 //zmw_get_wlan_dev(dev);
2847
2848 //zmw_declare_for_critical_section();
2849
2850
2851 /*
2852 * TBD : Maximum size of management frame
2853 */
2854 buf = zfwBufAllocate(dev, 1024);
2855 if (buf == NULL)
2856 {
2857 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
2858 return ZM_SUCCESS;
2859 }
2860
2861 /*
2862 * Reserve room for wlan header
2863 */
2864 offset = hlen;
2865
2866 /*
2867 * add addba frame body
2868 */
2869 offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up);
2870
2871
2872 zfwBufSetSize(dev, buf, offset);
2873
2874 /*
2875 * Copy wlan header
2876 */
2877 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
2878 for (i=0; i<(hlen>>1); i++)
2879 {
2880 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
2881 }
2882
2883 /* Get buffer DMA address */
2884 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
2885 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
2886 //{
2887 // goto zlError;
2888 //}
2889
2890 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
2891 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
2892 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
2893 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
2894 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
2895 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
2896
2897 #if 0
2898 err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
2899 ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
2900 if (err != ZM_SUCCESS)
2901 {
2902 goto zlError;
2903 }
2904 #else
2905 zfPutVmmq(dev, buf);
2906 zfPushVtxq(dev);
2907 #endif
2908
2909 return ZM_SUCCESS;
2910
2911 }
2912
2913 u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up)
2914 {
2915 u16_t ba_parameter, start_seq;
2916
2917 zmw_get_wlan_dev(dev);
2918
2919 //zmw_declare_for_critical_section();
2920 /*
2921 * ADDBA Request frame body
2922 */
2923
2924 /*
2925 * Category
2926 */
2927 zmw_tx_buf_writeb(dev, buf, offset++, 3);
2928 /*
2929 * Action details = 0
2930 */
2931 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME);
2932 /*
2933 * Dialog Token = nonzero
2934 * TBD: define how to get dialog token?
2935 */
2936 zmw_tx_buf_writeb(dev, buf, offset++, 2);
2937 /*
2938 * Block Ack parameter set
2939 * BA policy = 1 for immediate BA, 0 for delayed BA
2940 * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80)
2941 * TBD: how to get buffer size?
2942 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
2943 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
2944 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
2945 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
2946 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
2947 */
2948 ba_parameter = 1 << 12; // buffer size = 0x40(64)
2949 ba_parameter |= up << 2; // tid = up
2950 ba_parameter |= 2; // ba policy = 1
2951 zmw_tx_buf_writeh(dev, buf, offset, ba_parameter);
2952 offset+=2;
2953 /*
2954 * BA timeout value
2955 */
2956 zmw_tx_buf_writeh(dev, buf, offset, 0);
2957 offset+=2;
2958 /*
2959 * BA starting sequence number
2960 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
2961 * ¢x B0 B3 ¢x B4 B15 ¢x
2962 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
2963 * ¢x Frag num(0) ¢x BA starting seq num ¢x
2964 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
2965 */
2966 start_seq = ((wd->seq[ac]) << 4) & 0xFFF0;
2967 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
2968 offset+=2;
2969
2970 return offset;
2971 }
2972
2973 u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst,
2974 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
2975 {
2976 u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header
2977 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
2978
2979 zmw_get_wlan_dev(dev);
2980
2981 zmw_declare_for_critical_section();
2982
2983 /*
2984 * Generate control setting
2985 */
2986 //bodyLen = zfwBufGetSize(dev, buf);
2987 header[0] = 24+len+4; //Length
2988 header[1] = 0x8; //MAC control, backoff + (ack)
2989
2990 #if 0
2991 /* CCK 1M */
2992 header[2] = 0x0f00; //PHY control L
2993 header[3] = 0x0000; //PHY control H
2994 #else
2995 /* OFDM 6M */
2996 header[2] = 0x0f01; //PHY control L
2997 header[3] = 0x000B; //PHY control H
2998 #endif
2999
3000 /*
3001 * Generate WLAN header
3002 * Frame control frame type and subtype
3003 */
3004 header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION;
3005 /*
3006 * Duration
3007 */
3008 header[4+1] = 0;
3009
3010 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)
3011 {
3012 header[4+8] = wd->sta.bssid[0];
3013 header[4+9] = wd->sta.bssid[1];
3014 header[4+10] = wd->sta.bssid[2];
3015 }
3016 else if (wd->wlanMode == ZM_MODE_PSEUDO)
3017 {
3018 /* Address 3 = 00:00:00:00:00:00 */
3019 header[4+8] = 0;
3020 header[4+9] = 0;
3021 header[4+10] = 0;
3022 }
3023 else if (wd->wlanMode == ZM_MODE_IBSS)
3024 {
3025 header[4+8] = wd->sta.bssid[0];
3026 header[4+9] = wd->sta.bssid[1];
3027 header[4+10] = wd->sta.bssid[2];
3028 }
3029 else if (wd->wlanMode == ZM_MODE_AP)
3030 {
3031 /* Address 3 = BSSID */
3032 header[4+8] = wd->macAddr[0];
3033 header[4+9] = wd->macAddr[1];
3034 header[4+10] = wd->macAddr[2] + (vap<<8);
3035 }
3036
3037 /* Address 1 = DA */
3038 header[4+2] = dst[0];
3039 header[4+3] = dst[1];
3040 header[4+4] = dst[2];
3041
3042 /* Address 2 = SA */
3043 header[4+5] = wd->macAddr[0];
3044 header[4+6] = wd->macAddr[1];
3045 if (wd->wlanMode == ZM_MODE_AP)
3046 {
3047 header[4+7] = wd->macAddr[2] + (vap<<8);
3048 }
3049 else
3050 {
3051 header[4+7] = wd->macAddr[2];
3052 }
3053
3054 /* Sequence Control */
3055 zmw_enter_critical_section(dev);
3056 header[4+11] = ((wd->mmseq++)<<4);
3057 zmw_leave_critical_section(dev);
3058
3059
3060 return hlen;
3061 }
3062
3063
3064 u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf)
3065 {
3066 u16_t category;
3067
3068 //zmw_get_wlan_dev(dev);
3069
3070 //zmw_declare_for_critical_section();
3071
3072 category = zmw_rx_buf_readb(dev, buf, 24);
3073
3074 switch (category)
3075 {
3076 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME:
3077 zfAggBlockAckActionFrame(dev, buf);
3078 break;
3079
3080 }
3081
3082 return ZM_SUCCESS;
3083 }
3084
3085
3086 u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf)
3087 {
3088 u8_t action;
3089
3090 //zmw_get_wlan_dev(dev);
3091
3092 //zmw_declare_for_critical_section();
3093
3094 action = zmw_rx_buf_readb(dev, buf, 25);
3095 #ifdef ZM_ENABLE_AGGREGATION
3096 switch (action)
3097 {
3098 case ZM_WLAN_ADDBA_REQUEST_FRAME:
3099 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request");
3100 zfAggRecvAddbaRequest(dev, buf);
3101 break;
3102 case ZM_WLAN_ADDBA_RESPONSE_FRAME:
3103 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response");
3104 zfAggRecvAddbaResponse(dev, buf);
3105 break;
3106 case ZM_WLAN_DELBA_FRAME:
3107 zfAggRecvDelba(dev, buf);
3108 break;
3109 }
3110 #endif
3111 return ZM_SUCCESS;
3112 }
3113
3114 u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf)
3115 {
3116 //u16_t dialog;
3117 struct aggBaFrameParameter bf;
3118 u16_t i;
3119 //zmw_get_wlan_dev(dev);
3120
3121 //zmw_declare_for_critical_section();
3122
3123 bf.buf = buf;
3124 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3125 /*
3126 * ba parameter set
3127 */
3128 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27);
3129 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3130 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3131 bf.buffer_size = (bf.ba_parameter >> 6);
3132 /*
3133 * BA timeout value
3134 */
3135 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29);
3136 /*
3137 * BA starting sequence number
3138 */
3139 bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4;
3140
3141 i=26;
3142 while(i < 32) {
3143 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i));
3144 i++;
3145 }
3146
3147 zfAggSendAddbaResponse(dev, &bf);
3148
3149 zfAggAddbaSetTidRx(dev, buf, &bf);
3150
3151 return ZM_SUCCESS;
3152 }
3153
3154 u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf)
3155 {
3156 u16_t i, ac, aid, fragOff;
3157 u16_t src[3];
3158 u16_t offset = 0;
3159 u8_t up;
3160 struct agg_tid_rx *tid_rx = NULL;
3161
3162 zmw_get_wlan_dev(dev);
3163
3164 zmw_declare_for_critical_section();
3165
3166 src[0] = zmw_rx_buf_readh(dev, buf, offset+10);
3167 src[1] = zmw_rx_buf_readh(dev, buf, offset+12);
3168 src[2] = zmw_rx_buf_readh(dev, buf, offset+14);
3169 aid = zfApFindSta(dev, src);
3170
3171 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff);
3172 ac = zcUpToAc[up&0x7] & 0x3;
3173
3174 ac = bf->tid;
3175
3176 for (i=0; i<ZM_AGG_POOL_SIZE ; i++)
3177 {
3178 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac))
3179 {
3180 tid_rx = wd->tid_rx[i];
3181 break;
3182 }
3183 }
3184
3185 if (!tid_rx)
3186 {
3187 for (i=0; i<ZM_AGG_POOL_SIZE; i++)
3188 {
3189 if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT)
3190 {
3191 tid_rx = wd->tid_rx[i];
3192 break;
3193 }
3194 }
3195 if (!tid_rx)
3196 return 0;
3197 }
3198
3199 zmw_enter_critical_section(dev);
3200
3201 tid_rx->aid = aid;
3202 tid_rx->ac = ac;
3203 tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE;
3204 tid_rx->seq_start = bf->ba_start_seq;
3205 tid_rx->baw_head = tid_rx->baw_tail = 0;
3206 tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0;
3207 zmw_leave_critical_section(dev);
3208
3209 return 0;
3210 }
3211
3212 u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf)
3213 {
3214 u16_t i,ac, aid=0;
3215 u16_t src[3];
3216 struct aggBaFrameParameter bf;
3217
3218 zmw_get_wlan_dev(dev);
3219
3220 //zmw_declare_for_critical_section();
3221
3222 src[0] = zmw_rx_buf_readh(dev, buf, 10);
3223 src[1] = zmw_rx_buf_readh(dev, buf, 12);
3224 src[2] = zmw_rx_buf_readh(dev, buf, 14);
3225
3226 if (wd->wlanMode == ZM_MODE_AP)
3227 aid = zfApFindSta(dev, src);
3228
3229
3230 bf.buf = buf;
3231 bf.dialog = zmw_rx_buf_readb(dev, buf, 26);
3232 bf.status_code = zmw_rx_buf_readh(dev, buf, 27);
3233 if (!bf.status_code)
3234 {
3235 wd->addbaComplete=1;
3236 }
3237
3238 /*
3239 * ba parameter set
3240 */
3241 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29);
3242 bf.ba_policy = (bf.ba_parameter >> 1) & 1;
3243 bf.tid = (bf.ba_parameter >> 2) & 0xF;
3244 bf.buffer_size = (bf.ba_parameter >> 6);
3245 /*
3246 * BA timeout value
3247 */
3248 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31);
3249
3250 i=26;
3251 while(i < 32) {
3252 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i));
3253 i++;
3254 }
3255
3256 ac = zcUpToAc[bf.tid&0x7] & 0x3;
3257
3258 //zmw_enter_critical_section(dev);
3259
3260 //wd->aggSta[aid].aggFlag[ac] = 0;
3261
3262 //zmw_leave_critical_section(dev);
3263
3264 return ZM_SUCCESS;
3265 }
3266
3267 u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf)
3268 {
3269 //zmw_get_wlan_dev(dev);
3270
3271 //zmw_declare_for_critical_section();
3272 return ZM_SUCCESS;
3273 }
3274
3275 u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf)
3276 {
3277 zbuf_t* buf;
3278 //u16_t addrTblSize;
3279 //struct zsAddrTbl addrTbl;
3280 //u16_t err;
3281 u16_t offset = 0;
3282 u16_t hlen = 32;
3283 u16_t header[(24+25+1)/2];
3284 u16_t vap = 0;
3285 u16_t i;
3286 u8_t encrypt = 0;
3287 u16_t dst[3];
3288
3289 //zmw_get_wlan_dev(dev);
3290
3291 //zmw_declare_for_critical_section();
3292
3293
3294 /*
3295 * TBD : Maximum size of management frame
3296 */
3297 buf = zfwBufAllocate(dev, 1024);
3298 if (buf == NULL)
3299 {
3300 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3301 return ZM_SUCCESS;
3302 }
3303
3304 /*
3305 * Reserve room for wlan header
3306 */
3307 offset = hlen;
3308
3309 /*
3310 * add addba frame body
3311 */
3312 offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset);
3313
3314
3315 zfwBufSetSize(dev, buf, offset);
3316
3317 /*
3318 * Copy wlan header
3319 */
3320
3321 dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10);
3322 dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12);
3323 dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14);
3324 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt);
3325 for (i=0; i<(hlen>>1); i++)
3326 {
3327 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3328 }
3329
3330 /* Get buffer DMA address */
3331 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3332 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3333 //{
3334 // goto zlError;
3335 //}
3336
3337 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3338 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3339 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3340 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3341 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3342 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3343
3344 #if 0
3345 err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3346 ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
3347 if (err != ZM_SUCCESS)
3348 {
3349 goto zlError;
3350 }
3351 #else
3352 zfPutVmmq(dev, buf);
3353 zfPushVtxq(dev);
3354 #endif
3355
3356 //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid);
3357 return ZM_SUCCESS;
3358
3359 }
3360
3361 u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf,
3362 struct aggBaFrameParameter *bf, u16_t offset)
3363 {
3364
3365 //zmw_get_wlan_dev(dev);
3366
3367 //zmw_declare_for_critical_section();
3368 /*
3369 * ADDBA Request frame body
3370 */
3371
3372 /*
3373 * Category
3374 */
3375 zmw_tx_buf_writeb(dev, buf, offset++, 3);
3376 /*
3377 * Action details = 0
3378 */
3379 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME);
3380 /*
3381 * Dialog Token = nonzero
3382 */
3383 zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog);
3384 /*
3385 * Status code
3386 */
3387 zmw_tx_buf_writeh(dev, buf, offset, 0);
3388 offset+=2;
3389 /*
3390 * Block Ack parameter set
3391 * BA policy = 1 for immediate BA, 0 for delayed BA
3392 * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80)
3393 * TBD: how to get TID number and buffer size?
3394 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3395 * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x
3396 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3397 * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x
3398 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3399 */
3400 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter);
3401 offset+=2;
3402 /*
3403 * BA timeout value
3404 */
3405 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout);
3406 offset+=2;
3407
3408 return offset;
3409 }
3410
3411 void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx)
3412 {
3413 struct aggBarControl aggBarControl;
3414 //zmw_get_wlan_dev(dev);
3415
3416 //zmw_declare_for_critical_section();
3417 //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3418 // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3419 aggBarControl.bar_ack_policy = 0;
3420 aggBarControl.multi_tid = 0;
3421 aggBarControl.compressed_bitmap = 0;
3422 aggBarControl.tid_info = tid_tx->tid;
3423 zfAggSendBar(dev, tid_tx, &aggBarControl);
3424
3425 return;
3426
3427 }
3428 /*
3429 * zfAggSendBar() refers zfAggSendAddbaRequest()
3430 */
3431 u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3432 {
3433 zbuf_t* buf;
3434 //u16_t addrTblSize;
3435 //struct zsAddrTbl addrTbl;
3436 //u16_t err;
3437 u16_t offset = 0;
3438 u16_t hlen = 16+8; /* mac header + control headers*/
3439 u16_t header[(8+24+1)/2];
3440 u16_t vap = 0;
3441 u16_t i;
3442 u8_t encrypt = 0;
3443
3444 //zmw_get_wlan_dev(dev);
3445
3446 //zmw_declare_for_critical_section();
3447
3448
3449 /*
3450 * TBD : Maximum size of management frame
3451 */
3452 buf = zfwBufAllocate(dev, 1024);
3453 if (buf == NULL)
3454 {
3455 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
3456 return ZM_SUCCESS;
3457 }
3458
3459 /*
3460 * Reserve room for wlan header
3461 */
3462 offset = hlen;
3463
3464 /*
3465 * add addba frame body
3466 */
3467 offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl);
3468
3469
3470 zfwBufSetSize(dev, buf, offset);
3471
3472 /*
3473 * Copy wlan header
3474 */
3475 zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt);
3476 for (i=0; i<(hlen>>1); i++)
3477 {
3478 zmw_tx_buf_writeh(dev, buf, i*2, header[i]);
3479 }
3480
3481 /* Get buffer DMA address */
3482 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0)
3483 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0)
3484 //{
3485 // goto zlError;
3486 //}
3487
3488 //zm_msg2_mm(ZM_LV_2, "offset=", offset);
3489 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen);
3490 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize);
3491 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]);
3492 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]);
3493 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data);
3494
3495 #if 0
3496 err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0,
3497 ZM_INTERNAL_ALLOC_BUF, 0, 0xff);
3498 if (err != ZM_SUCCESS)
3499 {
3500 goto zlError;
3501 }
3502 #else
3503 zfPutVmmq(dev, buf);
3504 zfPushVtxq(dev);
3505 #endif
3506
3507 return ZM_SUCCESS;
3508
3509 }
3510
3511 u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl)
3512 {
3513 u16_t bar_control, start_seq;
3514
3515 //zmw_get_wlan_dev(dev);
3516
3517 //zmw_declare_for_critical_section();
3518 /*
3519 * BAR Control frame body
3520 */
3521
3522 /*
3523 * BAR Control Field
3524 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3525 * ¢x B0 ¢x B1 ¢x B2 ¢x B3 B11 ¢x B12 B15 ¢x
3526 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3527 * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x
3528 * ¢x Policy ¢x ¢x Bitmap ¢x ¢x ¢x
3529 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3530 */
3531 bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2
3532 | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy;
3533
3534 zmw_tx_buf_writeh(dev, buf, offset, bar_control);
3535 offset+=2;
3536 if (0 == aggBarControl->multi_tid) {
3537 /*
3538 * BA starting sequence number
3539 * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{
3540 * ¢x B0 B3 ¢x B4 B15 ¢x
3541 * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t
3542 * ¢x Frag num(0) ¢x BA starting seq num ¢x
3543 * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢}
3544 */
3545 start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0;
3546 zmw_tx_buf_writeh(dev, buf, offset, start_seq);
3547 offset+=2;
3548 }
3549 if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) {
3550 /* multi-tid BlockAckReq variant, not implemented*/
3551 }
3552
3553 return offset;
3554 }
3555
3556 u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst,
3557 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt)
3558 {
3559 u8_t hlen = 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header
3560 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION;
3561
3562 zmw_get_wlan_dev(dev);
3563
3564 zmw_declare_for_critical_section();
3565
3566 /*
3567 * Generate control setting
3568 */
3569 //bodyLen = zfwBufGetSize(dev, buf);
3570 header[0] = 16+len+4; //Length
3571 header[1] = 0x8; //MAC control, backoff + (ack)
3572
3573 #if 1
3574 /* CCK 1M */
3575 header[2] = 0x0f00; //PHY control L
3576 header[3] = 0x0000; //PHY control H
3577 #else
3578 /* CCK 6M */
3579 header[2] = 0x0f01; //PHY control L
3580 header[3] = 0x000B; //PHY control H
3581
3582 #endif
3583 /*
3584 * Generate WLAN header
3585 * Frame control frame type and subtype
3586 */
3587 header[4+0] = ZM_WLAN_FRAME_TYPE_BAR;
3588 /*
3589 * Duration
3590 */
3591 header[4+1] = 0;
3592
3593 /* Address 1 = DA */
3594 header[4+2] = dst[0];
3595 header[4+3] = dst[1];
3596 header[4+4] = dst[2];
3597
3598 /* Address 2 = SA */
3599 header[4+5] = wd->macAddr[0];
3600 header[4+6] = wd->macAddr[1];
3601 if (wd->wlanMode == ZM_MODE_AP)
3602 {
3603 #ifdef ZM_VAPMODE_MULTILE_SSID
3604 header[4+7] = wd->macAddr[2]; //Multiple SSID
3605 #else
3606 header[4+7] = wd->macAddr[2] + (vap<<8); //VAP
3607 #endif
3608 }
3609 else
3610 {
3611 header[4+7] = wd->macAddr[2];
3612 }
3613
3614 /* Sequence Control */
3615 zmw_enter_critical_section(dev);
3616 header[4+11] = ((wd->mmseq++)<<4);
3617 zmw_leave_critical_section(dev);
3618
3619
3620 return hlen;
3621 }