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 29extern u8_t zcUpToAc[8]; 30const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0}; 31 32 33u16_t aggr_count; 34u32_t success_mpdu; 35u32_t total_mpdu; 36 37void zfAggInit(zdev_t* dev) 38{ 39 u16_t i,j; 40 41 zmw_get_wlan_dev(dev); 42 43 zmw_declare_for_critical_section(); 44 /* 45 * 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 153u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf) 154{ 155 u16_t id; 156 u16_t dst[3]; 157 158 zmw_get_wlan_dev(dev); 159 160 zmw_declare_for_critical_section(); 161 162 dst[0] = zmw_rx_buf_readh(dev, buf, 0); 163 dst[1] = zmw_rx_buf_readh(dev, buf, 2); 164 dst[2] = zmw_rx_buf_readh(dev, buf, 4); 165 166 zmw_enter_critical_section(dev); 167 168 if(wd->wlanMode == ZM_MODE_AP) { 169 id = zfApFindSta(dev, dst); 170 } 171 else { 172 id = 0; 173 } 174 zmw_leave_critical_section(dev); 175 176#if ZM_AGG_FPGA_DEBUG 177 id = 0; 178#endif 179 180 return id; 181} 182 183 184/************************************************************************/ 185/* */ 186/* 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/************************************************************************/ 202TID_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/************************************************************************/ 245TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf) 246{ 247 u16_t i; 248 TID_TX tid_tx=NULL; 249 u16_t ac = zcUpToAc[tid&0x7] & 0x3; 250 zmw_get_wlan_dev(dev); 251 252 zmw_declare_for_critical_section(); 253 254 /* 255 * 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/************************************************************************/ 317u16_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 401u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq) { 402 struct dest* dest; 403 u16_t exist = 0; 404 zmw_get_wlan_dev(dev); 405 406 zmw_declare_for_critical_section(); 407 408 zmw_enter_critical_section(dev); 409 if (!DESTQ.Head[ac]) { 410 exist = 0; 411 } 412 else { 413 dest = DESTQ.Head[ac]; 414 if (dest->tid_tx == tid_tx) { 415 exist = 1; 416 } 417 else { 418 while (dest->next != DESTQ.Head[ac]) { 419 dest = dest->next; 420 if (dest->tid_tx == tid_tx){ 421 exist = 1; 422 break; 423 } 424 } 425 } 426 } 427 428 zmw_leave_critical_section(dev); 429 430 return exist; 431} 432 433void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq) 434{ 435 struct dest* new_dest; 436 zmw_get_wlan_dev(dev); 437 438 zmw_declare_for_critical_section(); 439 440 new_dest = zfwMemAllocate(dev, sizeof(struct dest)); 441 if(!new_dest) 442 { 443 return; 444 } 445 new_dest->Qtype = Qtype; 446 new_dest->tid_tx = tid_tx; 447 if (0 == Qtype) 448 new_dest->tid_tx = tid_tx; 449 else 450 new_dest->vtxq = vtxq; 451 if (!DESTQ.Head[ac]) { 452 453 zmw_enter_critical_section(dev); 454 new_dest->next = new_dest; 455 DESTQ.Head[ac] = DESTQ.dest[ac] = new_dest; 456 zmw_leave_critical_section(dev); 457 } 458 else { 459 460 zmw_enter_critical_section(dev); 461 new_dest->next = DESTQ.dest[ac]->next; 462 DESTQ.dest[ac]->next = new_dest; 463 zmw_leave_critical_section(dev); 464 } 465 466 467 //DESTQ.size[ac]++; 468 return; 469} 470 471void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq) 472{ 473 struct dest* dest, *temp; 474 u16_t i; 475 476 zmw_get_wlan_dev(dev); 477 478 zmw_declare_for_critical_section(); 479 480 zmw_enter_critical_section(dev); 481 if (wd->destLock) { 482 zmw_leave_critical_section(dev); 483 return; 484 } 485 486 487 //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 542void 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 564struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac) 565{ 566 struct dest *dest = NULL; 567 zmw_get_wlan_dev(dev); 568 569 zmw_declare_for_critical_section(); 570 571 zmw_enter_critical_section(dev); 572 if (DESTQ.dest[ac]) { 573 dest = DESTQ.dest[ac]; 574 DESTQ.dest[ac] = DESTQ.dest[ac]->next; 575 } 576 else { 577 dest = NULL; 578 } 579 zmw_leave_critical_section(dev); 580 581 return dest; 582} 583 584#ifdef ZM_ENABLE_AGGREGATION 585#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW 586u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo *buf_info,TID_TX tid_tx) 587{ 588 zbuf_t* buf; 589 u32_t time; 590 struct baw_header *baw_header; 591 592 zmw_get_wlan_dev(dev); 593 594 zmw_declare_for_critical_section(); 595 596 597 buf = buf_info->buf; 598 599 zmw_enter_critical_section(dev); 600 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); 601 zmw_leave_critical_section(dev); 602 603 if (tid_tx->size >= (ZM_AGGQ_SIZE - 2)) { 604 zfwBufFree(dev, buf, ZM_SUCCESS); 605 return 0; 606 } 607 608 zmw_enter_critical_section(dev); 609 tid_tx->aggTail = (tid_tx->aggTail == 0)? ZM_AGGQ_SIZE_MASK: tid_tx->aggTail - 1; 610 tid_tx->aggvtxq[tid_tx->aggTail].buf = buf; 611 //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 642void 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 658TID_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 683u16_t zfAggValidTidTx(zdev_t* dev, TID_TX tid_tx) { 684 u16_t i, valid = 0; 685 zmw_get_wlan_dev(dev); 686 687 zmw_declare_for_critical_section(); 688 689 zmw_enter_critical_section(dev); 690 for (i=0; i<ZM_AGG_POOL_SIZE; i++) 691 { 692 if (wd->aggQPool[i] == tid_tx) 693 { 694 valid = 1; 695 break; 696 } 697 else { 698 } 699 } 700 zmw_leave_critical_section(dev); 701 702 return valid; 703} 704 705void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear) 706{ 707 TID_TX tid_tx = NULL; 708 void* vtxq; 709 struct dest* dest; 710 zbuf_t* buf; 711 u32_t txql, min_txql; 712 //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/************************************************************************/ 878u16_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/************************************************************************/ 1031u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac) 1032{ 1033 u16_t i; 1034 u16_t readycount = 0; 1035 1036 zmw_get_wlan_dev(dev); 1037 1038 zmw_declare_for_critical_section(); 1039 1040 zmw_enter_critical_section(dev); 1041 1042 for (i=0 ; i<ZM_AGG_POOL_SIZE; i++) 1043 { 1044 if (wd->aggQPool[i]->aggQEnabled && (wd->aggQPool[i]->aggReady || \ 1045 wd->aggQPool[i]->clearFlag) && ac == wd->aggQPool[i]->ac) 1046 readycount++; 1047 } 1048 1049 zmw_leave_critical_section(dev); 1050 1051 return readycount; 1052} 1053 1054/************************************************************************/ 1055/* */ 1056/* 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/************************************************************************/ 1074u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount) 1075{ 1076 u16_t qlen; 1077 u16_t partial; 1078 1079 zmw_get_wlan_dev(dev); 1080 1081 zmw_declare_for_critical_section(); 1082 1083 zmw_enter_critical_section(dev); 1084 1085 qlen = zm_agg_qlen(dev, wd->vtxqHead[ac], wd->vtxqTail[ac]); 1086 1087 if ((qlen + readycount) > 0) 1088 { 1089 partial = (u16_t)( zm_agg_weight(ac) * ((u16_t)qlen/(qlen + \ 1090 readycount)) ); 1091 } 1092 else 1093 { 1094 partial = 0; 1095 } 1096 1097 zmw_leave_critical_section(dev); 1098 1099 if (partial > qlen) 1100 partial = qlen; 1101 1102 return partial; 1103} 1104 1105 1106/************************************************************************/ 1107/* */ 1108/* 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/************************************************************************/ 1125u16_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/************************************************************************/ 1285TID_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/************************************************************************/ 1336zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx) 1337{ 1338 zbuf_t* buf = NULL; 1339 1340 zmw_declare_for_critical_section(); 1341 1342 if (tid_tx->aggHead != tid_tx->aggTail) 1343 { 1344 buf = tid_tx->aggvtxq[ tid_tx->aggTail ].buf; 1345 1346 tid_tx->aggvtxq[tid_tx->aggTail].buf = NULL; 1347 1348 zmw_enter_critical_section(dev); 1349 tid_tx->aggTail = ((tid_tx->aggTail + 1) & ZM_AGGQ_SIZE_MASK); 1350 if(tid_tx->size > 0) tid_tx->size--; 1351 tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); 1352 if (NULL == buf) { 1353 //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/************************************************************************/ 1391u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum) 1392{ 1393 u16_t ac, tid; 1394 struct aggQueue *tx_tid; 1395 struct aggSta *agg_sta; 1396 1397 zmw_get_wlan_dev(dev); 1398 1399 zmw_declare_for_critical_section(); 1400 1401 tx_tid = wd->aggQPool[qnum]; 1402 agg_sta = &wd->aggSta[tx_tid->aggQSTA]; 1403 ac = tx_tid->ac; 1404 tid = tx_tid->tid; 1405 1406 zmw_enter_critical_section(dev); 1407 1408 tx_tid->aggQEnabled = 0; 1409 tx_tid->aggHead = tx_tid->aggTail = 0; 1410 tx_tid->aggReady = 0; 1411 tx_tid->clearFlag = tx_tid->deleteFlag = 0; 1412 tx_tid->size = 0; 1413 agg_sta->count[ac] = 0; 1414 1415 agg_sta->tid_tx[tid] = NULL; 1416 agg_sta->aggFlag[ac] = 0; 1417 1418 zmw_leave_critical_section(dev); 1419 1420 zm_msg1_agg(ZM_LV_0, "queue deleted! qnum=", qnum); 1421 1422 return ZM_SUCCESS; 1423} 1424 1425#ifdef ZM_ENABLE_AGGREGATION 1426#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW 1427void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen) { 1428 TID_BAW tid_baw; 1429 s16_t i; 1430 zbuf_t* buf; 1431 struct bufInfo *buf_info; 1432 1433 zmw_get_wlan_dev(dev); 1434 //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 1460void 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 1486TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx) { 1487 TID_BAW tid_baw=NULL; 1488 TID_BAW next_baw=NULL; 1489 u16_t i; 1490 zmw_get_wlan_dev(dev); 1491 //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 1523u16_t zfBawInsert(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r) { 1524 //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 1558struct 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 1580void 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 1591void 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 1609TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq) { 1610 TID_BAW tid_baw=NULL; 1611 u16_t i; 1612 1613 zmw_get_wlan_dev(dev); 1614 //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 1633u16_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/************************************************************************/ 1672u16_t zfAggScanAndClear(zdev_t* dev, u32_t time) 1673{ 1674 u16_t i; 1675 u16_t head; 1676 u16_t tail; 1677 u32_t tick; 1678 u32_t arrivalTime; 1679 //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 1753u16_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 1799u16_t zfAggRxClear(zdev_t* dev, u32_t time) 1800{ 1801 u16_t i; 1802 struct agg_tid_rx *tid_rx; 1803 1804 zmw_get_wlan_dev(dev); 1805 1806 zmw_declare_for_critical_section(); 1807 1808 for (i=0; i<ZM_AGG_POOL_SIZE; i++) 1809 { 1810 zmw_enter_critical_section(dev); 1811 tid_rx = wd->tid_rx[i]; 1812 if (tid_rx->baw_head != tid_rx->baw_tail) 1813 { 1814 u16_t j = tid_rx->baw_tail; 1815 while ((j != tid_rx->baw_head) && !tid_rx->frame[j].buf) { 1816 j = (j + 1) & ZM_AGG_BAW_MASK; 1817 } 1818 if ((j != tid_rx->baw_head) && (time - tid_rx->frame[j].arrivalTime) > 1819 (ZM_AGG_CLEAR_TIME - 5)) 1820 { 1821 zmw_leave_critical_section(dev); 1822 zm_msg0_agg(ZM_LV_1, "queue RxFlush by RxClear"); 1823 zfAggRxFlush(dev, 0, tid_rx); 1824 zmw_enter_critical_section(dev); 1825 } 1826 } 1827 zmw_leave_critical_section(dev); 1828 } 1829 1830 return ZM_SUCCESS; 1831} 1832 1833struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf) 1834{ 1835 u16_t dst0, src[3], 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 1914u16_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 2056struct 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 2092u16_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 2259u16_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/************************************************************************/ 2330u16_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 2362 zmw_enter_critical_section(dev); 2363 tid_rx->seq_start = 0; 2364 tid_rx->baw_head = tid_rx->baw_tail = 0; 2365 tid_rx->aid = ZM_MAX_STA_SUPPORT; 2366 zmw_leave_critical_section(dev); 2367 2368 #ifdef ZM_ENABLE_AGGREGATION 2369 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW 2370 if (tid_baw->enabled) { 2371 zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i); 2372 BAW->disable(dev, tid_baw); 2373 } 2374 #endif 2375 #endif 2376 if (1 == wd->aggQPool[i]->aggQEnabled) { 2377 tid_tx = wd->aggQPool[i]; 2378 buf = zfAggTxGetVtxq(dev, tid_tx); 2379 while (buf) { 2380 zfwBufFree(dev, buf, 0); 2381 buf = zfAggTxGetVtxq(dev, tid_tx); 2382 } 2383 } 2384 2385 if(destroy) { 2386 zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue)); 2387 zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx)); 2388 } 2389 } 2390 #ifdef ZM_ENABLE_AGGREGATION 2391 #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW 2392 if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler)); 2393 #endif 2394 #endif 2395 return ZM_SUCCESS; 2396} 2397 2398 2399void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) { 2400 u16_t start_seq, len; 2401 u8_t i, bitmap[8]; 2402 len = zfwBufGetSize(dev, buf); 2403 start_seq = zmw_rx_buf_readh(dev, buf, len-2); 2404 DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4); 2405 /* todo: set the bitmap by reordering buffer! */ 2406 for (i=0; i<8; i++) bitmap[i]=0; 2407 zfSendBA(dev, start_seq, bitmap); 2408} 2409 2410#ifdef ZM_ENABLE_AGGREGATION 2411#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW 2412void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) { 2413 u16_t removeLen; 2414 u16_t err; 2415 2416 zmw_get_wlan_dev(dev); 2417 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) { 2418 tid_tx->bar_ssn = buf_info->baw_header->header[15]; 2419 aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4; 2420 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4); 2421 } 2422 buf_info->baw_header->header[4] |= (1 << 11); 2423 if (aggControl && aggControl->aggEnabled) { 2424 //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1)) 2425 //{ 2426 //if (((buf_info->baw_header->header[2] & 0x3) == 2)) 2427 //{ 2428 /* Enable aggregation */ 2429 buf_info->baw_header->header[1] |= 0x20; 2430 if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) { 2431 buf_info->baw_header->header[1] |= 0x4000; 2432 } 2433 else { 2434 buf_info->baw_header->header[1] &= ~0x4000; 2435 //zm_debug_msg0("ZM_AGG_LAST_MPDU"); 2436 } 2437 //} 2438 //else { 2439 // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3) 2440 // aggControl->aggEnabled = 0; 2441 //} 2442 //} 2443 //else { 2444 // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation); 2445 // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1)); 2446 // aggControl->aggEnabled = 0; 2447 //} 2448 } 2449 2450 /*if (aggControl->tid_baw) { 2451 struct baw_header_r header_r; 2452 2453 header_r.header = buf_info->baw_header->header; 2454 header_r.mic = buf_info->baw_header->mic; 2455 header_r.snap = buf_info->baw_header->snap; 2456 header_r.headerLen = buf_info->baw_header->headerLen; 2457 header_r.micLen = buf_info->baw_header->micLen; 2458 header_r.snapLen = buf_info->baw_header->snapLen; 2459 header_r.removeLen = buf_info->baw_header->removeLen; 2460 header_r.keyIdx = buf_info->baw_header->keyIdx; 2461 2462 BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r); 2463 }*/ 2464 2465 err = zfHpSend(dev, 2466 buf_info->baw_header->header, 2467 buf_info->baw_header->headerLen, 2468 buf_info->baw_header->snap, 2469 buf_info->baw_header->snapLen, 2470 buf_info->baw_header->mic, 2471 buf_info->baw_header->micLen, 2472 buf_info->buf, 2473 buf_info->baw_header->removeLen, 2474 ZM_EXTERNAL_ALLOC_BUF, 2475 (u8_t)tid_tx->ac, 2476 buf_info->baw_header->keyIdx); 2477 if (err != ZM_SUCCESS) 2478 { 2479 goto zlError; 2480 } 2481 2482 return; 2483 2484zlError: 2485 zfwBufFree(dev, buf_info->buf, 0); 2486 return; 2487 2488} 2489#endif //disable BAW 2490#endif 2491/************************************************************************/ 2492/* */ 2493/* FUNCTION DESCRIPTION zfAggTxSendEth */ 2494/* Called to transmit Ethernet frame from upper elayer. */ 2495/* */ 2496/* INPUTS */ 2497/* dev : device pointer */ 2498/* buf : buffer pointer */ 2499/* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */ 2500/* */ 2501/* OUTPUTS */ 2502/* error code */ 2503/* */ 2504/* AUTHOR */ 2505/* Stephen, Honda Atheros Communications, Inc. 2006.12 */ 2506/* */ 2507/************************************************************************/ 2508u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx) 2509{ 2510 u16_t err; 2511 //u16_t addrTblSize; 2512 //struct zsAddrTbl addrTbl; 2513 u16_t removeLen; 2514 u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */ 2515 u16_t headerLen; 2516 u16_t mic[8/2]; 2517 u16_t micLen; 2518 u16_t snap[8/2]; 2519 u16_t snapLen; 2520 u16_t fragLen; 2521 u16_t frameLen; 2522 u16_t fragNum; 2523 struct zsFrag frag; 2524 u16_t i, id; 2525 u16_t da[3]; 2526 u16_t sa[3]; 2527 u8_t up; 2528 u8_t qosType, keyIdx = 0; 2529 u16_t fragOff; 2530 2531 zmw_get_wlan_dev(dev); 2532 2533 zmw_declare_for_critical_section(); 2534 2535 zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port); 2536 2537 /* Get IP TOS for QoS AC and IP frag offset */ 2538 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); 2539 2540#ifdef ZM_ENABLE_NATIVE_WIFI 2541 if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) 2542 { 2543 /* DA */ 2544 da[0] = zmw_tx_buf_readh(dev, buf, 16); 2545 da[1] = zmw_tx_buf_readh(dev, buf, 18); 2546 da[2] = zmw_tx_buf_readh(dev, buf, 20); 2547 /* SA */ 2548 sa[0] = zmw_tx_buf_readh(dev, buf, 10); 2549 sa[1] = zmw_tx_buf_readh(dev, buf, 12); 2550 sa[2] = zmw_tx_buf_readh(dev, buf, 14); 2551 } 2552 else if ( wd->wlanMode == ZM_MODE_IBSS ) 2553 { 2554 /* DA */ 2555 da[0] = zmw_tx_buf_readh(dev, buf, 4); 2556 da[1] = zmw_tx_buf_readh(dev, buf, 6); 2557 da[2] = zmw_tx_buf_readh(dev, buf, 8); 2558 /* SA */ 2559 sa[0] = zmw_tx_buf_readh(dev, buf, 10); 2560 sa[1] = zmw_tx_buf_readh(dev, buf, 12); 2561 sa[2] = zmw_tx_buf_readh(dev, buf, 14); 2562 } 2563 else if ( wd->wlanMode == ZM_MODE_AP ) 2564 { 2565 /* DA */ 2566 da[0] = zmw_tx_buf_readh(dev, buf, 4); 2567 da[1] = zmw_tx_buf_readh(dev, buf, 6); 2568 da[2] = zmw_tx_buf_readh(dev, buf, 8); 2569 /* SA */ 2570 sa[0] = zmw_tx_buf_readh(dev, buf, 16); 2571 sa[1] = zmw_tx_buf_readh(dev, buf, 18); 2572 sa[2] = zmw_tx_buf_readh(dev, buf, 20); 2573 } 2574 else 2575 { 2576 // 2577 } 2578#else 2579 /* DA */ 2580 da[0] = zmw_tx_buf_readh(dev, buf, 0); 2581 da[1] = zmw_tx_buf_readh(dev, buf, 2); 2582 da[2] = zmw_tx_buf_readh(dev, buf, 4); 2583 /* SA */ 2584 sa[0] = zmw_tx_buf_readh(dev, buf, 6); 2585 sa[1] = zmw_tx_buf_readh(dev, buf, 8); 2586 sa[2] = zmw_tx_buf_readh(dev, buf, 10); 2587#endif 2588 //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m) 2589 if (wd->wlanMode == ZM_MODE_AP) 2590 { 2591 keyIdx = wd->ap.bcHalKeyIdx[port]; 2592 id = zfApFindSta(dev, da); 2593 if (id != 0xffff) 2594 { 2595 switch (wd->ap.staTable[id].encryMode) 2596 { 2597 case ZM_AES: 2598 case ZM_TKIP: 2599#ifdef ZM_ENABLE_CENC 2600 case ZM_CENC: 2601#endif //ZM_ENABLE_CENC 2602 keyIdx = wd->ap.staTable[id].keyIdx; 2603 break; 2604 } 2605 } 2606 } 2607 else 2608 { 2609 switch (wd->sta.encryMode) 2610 { 2611 case ZM_WEP64: 2612 case ZM_WEP128: 2613 case ZM_WEP256: 2614 keyIdx = wd->sta.keyId; 2615 break; 2616 case ZM_AES: 2617 case ZM_TKIP: 2618 if ((da[0]& 0x1)) 2619 keyIdx = 5; 2620 else 2621 keyIdx = 4; 2622 break; 2623#ifdef ZM_ENABLE_CENC 2624 case ZM_CENC: 2625 keyIdx = wd->sta.cencKeyId; 2626 break; 2627#endif //ZM_ENABLE_CENC 2628 } 2629 } 2630 2631 /* Create SNAP */ 2632 removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen); 2633 //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff); 2634 2635 fragLen = wd->fragThreshold; 2636 frameLen = zfwBufGetSize(dev, buf); 2637 frameLen -= removeLen; 2638 2639 if ( frameLen > fragLen ) 2640 { 2641 micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic); 2642 } 2643 else 2644 { 2645 /* append MIC by HMAC */ 2646 micLen = 0; 2647 } 2648 2649 /* Access Category */ 2650 if (wd->wlanMode == ZM_MODE_AP) 2651 { 2652 zfApGetStaQosType(dev, da, &qosType); 2653 if (qosType == 0) 2654 { 2655 up = 0; 2656 } 2657 } 2658 else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) 2659 { 2660 if (wd->sta.wmeConnected == 0) 2661 { 2662 up = 0; 2663 } 2664 } 2665 else 2666 { 2667 /* TODO : STA QoS control field */ 2668 up = 0; 2669 } 2670 2671 /* Assign sequence number */ 2672 zmw_enter_critical_section(dev); 2673 frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4); 2674 if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) { 2675 tid_tx->bar_ssn = frag.seq[0]; 2676 2677 zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4); 2678 } 2679 //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0]; 2680 zmw_leave_critical_section(dev); 2681 2682 2683 frag.buf[0] = buf; 2684 frag.bufType[0] = bufType; 2685 frag.flag[0] = flag; 2686 fragNum = 1; 2687 2688 for (i=0; i<fragNum; i++) 2689 { 2690 /* Create WLAN header(Control Setting + 802.11 header + IV) */ 2691 if (up !=0 ) zm_debug_msg1("up not 0, up=",up); 2692 headerLen = zfTxGenWlanHeader(dev, frag.buf[i], header, frag.seq[i], 2693 frag.flag[i], snapLen+micLen, removeLen, 2694 port, da, sa, up, &micLen, snap, snapLen, 2695 aggControl); 2696 2697 /* Get buffer DMA address */ 2698 //if ((addrTblSize = zfwBufMapDma(dev, frag.buf[i], &addrTbl)) == 0) 2699 //if ((addrTblSize = zfwMapTxDma(dev, frag.buf[i], &addrTbl)) == 0) 2700 //{ 2701 // err = ZM_ERR_BUFFER_DMA_ADDR; 2702 // goto zlError; 2703 //} 2704 2705 /* Flush buffer on cache */ 2706 //zfwBufFlush(dev, frag.buf[i]); 2707 2708 2709 fragLen = zfwBufGetSize(dev, frag.buf[i]); 2710 if ((da[0]&0x1) == 0) 2711 { 2712 wd->commTally.txUnicastFrm++; 2713 wd->commTally.txUnicastOctets += (fragLen+snapLen); 2714 } 2715 else if ((da[0]& 0x1)) 2716 { 2717 wd->commTally.txBroadcastFrm++; 2718 wd->commTally.txBroadcastOctets += (fragLen+snapLen); 2719 } 2720 else 2721 { 2722 wd->commTally.txMulticastFrm++; 2723 wd->commTally.txMulticastOctets += (fragLen+snapLen); 2724 } 2725 wd->ledStruct.txTraffic++; 2726 2727 2728 /*if (aggControl->tid_baw && aggControl->aggEnabled) { 2729 struct baw_header_r header_r; 2730 2731 header_r.header = header; 2732 header_r.mic = mic; 2733 header_r.snap = snap; 2734 header_r.headerLen = headerLen; 2735 header_r.micLen = micLen; 2736 header_r.snapLen = snapLen; 2737 header_r.removeLen = removeLen; 2738 header_r.keyIdx = keyIdx; 2739 2740 BAW->insert(dev, buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, 0, &header_r); 2741 }*/ 2742 2743 err = zfHpSend(dev, header, headerLen, snap, snapLen, 2744 mic, micLen, frag.buf[i], removeLen, 2745 frag.bufType[i], zcUpToAc[up&0x7], keyIdx); 2746 if (err != ZM_SUCCESS) 2747 { 2748 goto zlError; 2749 } 2750 2751 2752 continue; 2753 2754zlError: 2755 if (frag.bufType[i] == ZM_EXTERNAL_ALLOC_BUF) 2756 { 2757 zfwBufFree(dev, frag.buf[i], err); 2758 } 2759 else if (frag.bufType[i] == ZM_INTERNAL_ALLOC_BUF) 2760 { 2761 zfwBufFree(dev, frag.buf[i], 0); 2762 } 2763 else 2764 { 2765 zm_assert(0); 2766 } 2767 } /* for (i=0; i<fragNum; i++) */ 2768 2769 return ZM_SUCCESS; 2770} 2771 2772/* 2773 * zfAggSendADDBA() refers zfSendMmFrame() in cmm.c 2774 */ 2775u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up) 2776{ 2777 zbuf_t* buf; 2778 //u16_t addrTblSize; 2779 //struct zsAddrTbl addrTbl; 2780 //u16_t err; 2781 u16_t offset = 0; 2782 u16_t hlen = 32; 2783 u16_t header[(24+25+1)/2]; 2784 u16_t vap = 0; 2785 u16_t i; 2786 u8_t encrypt = 0; 2787 2788 //zmw_get_wlan_dev(dev); 2789 2790 //zmw_declare_for_critical_section(); 2791 2792 2793 /* 2794 * TBD : Maximum size of management frame 2795 */ 2796 buf = zfwBufAllocate(dev, 1024); 2797 if (buf == NULL) 2798 { 2799 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); 2800 return ZM_SUCCESS; 2801 } 2802 2803 /* 2804 * Reserve room for wlan header 2805 */ 2806 offset = hlen; 2807 2808 /* 2809 * add addba frame body 2810 */ 2811 offset = zfAggSetAddbaFrameBody(dev, buf, offset, ac, up); 2812 2813 2814 zfwBufSetSize(dev, buf, offset); 2815 2816 /* 2817 * Copy wlan header 2818 */ 2819 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt); 2820 for (i=0; i<(hlen>>1); i++) 2821 { 2822 zmw_tx_buf_writeh(dev, buf, i*2, header[i]); 2823 } 2824 2825 /* Get buffer DMA address */ 2826 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) 2827 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) 2828 //{ 2829 // goto zlError; 2830 //} 2831 2832 //zm_msg2_mm(ZM_LV_2, "offset=", offset); 2833 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen); 2834 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); 2835 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); 2836 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); 2837 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); 2838 2839 zfPutVmmq(dev, buf); 2840 zfPushVtxq(dev); 2841 2842 return ZM_SUCCESS; 2843 2844} 2845 2846u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up) 2847{ 2848 u16_t ba_parameter, start_seq; 2849 2850 zmw_get_wlan_dev(dev); 2851 2852 //zmw_declare_for_critical_section(); 2853 /* 2854 * ADDBA Request frame body 2855 */ 2856 2857 /* 2858 * Category 2859 */ 2860 zmw_tx_buf_writeb(dev, buf, offset++, 3); 2861 /* 2862 * Action details = 0 2863 */ 2864 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME); 2865 /* 2866 * Dialog Token = nonzero 2867 * TBD: define how to get dialog token? 2868 */ 2869 zmw_tx_buf_writeb(dev, buf, offset++, 2); 2870 /* 2871 * Block Ack parameter set 2872 * BA policy = 1 for immediate BA, 0 for delayed BA 2873 * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80) 2874 * TBD: how to get buffer size? 2875 * �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�{ 2876 * �x B0 �x B1 �x B2 B5 �x B6 B15 �x 2877 * �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 2878 * �x Reserved �x BA policy �x TID �x Buffer size �x 2879 * �|�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�} 2880 */ 2881 ba_parameter = 1 << 12; // buffer size = 0x40(64) 2882 ba_parameter |= up << 2; // tid = up 2883 ba_parameter |= 2; // ba policy = 1 2884 zmw_tx_buf_writeh(dev, buf, offset, ba_parameter); 2885 offset+=2; 2886 /* 2887 * BA timeout value 2888 */ 2889 zmw_tx_buf_writeh(dev, buf, offset, 0); 2890 offset+=2; 2891 /* 2892 * BA starting sequence number 2893 * �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�{ 2894 * �x B0 B3 �x B4 B15 �x 2895 * �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 2896 * �x Frag num(0) �x BA starting seq num �x 2897 * �|�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�} 2898 */ 2899 start_seq = ((wd->seq[ac]) << 4) & 0xFFF0; 2900 zmw_tx_buf_writeh(dev, buf, offset, start_seq); 2901 offset+=2; 2902 2903 return offset; 2904} 2905 2906u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst, 2907 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt) 2908{ 2909 u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header 2910 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION; 2911 2912 zmw_get_wlan_dev(dev); 2913 2914 zmw_declare_for_critical_section(); 2915 2916 /* 2917 * Generate control setting 2918 */ 2919 //bodyLen = zfwBufGetSize(dev, buf); 2920 header[0] = 24+len+4; //Length 2921 header[1] = 0x8; //MAC control, backoff + (ack) 2922 2923 /* OFDM 6M */ 2924 header[2] = 0x0f01; //PHY control L 2925 header[3] = 0x000B; //PHY control H 2926 2927 /* 2928 * Generate WLAN header 2929 * Frame control frame type and subtype 2930 */ 2931 header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION; 2932 /* 2933 * Duration 2934 */ 2935 header[4+1] = 0; 2936 2937 if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) 2938 { 2939 header[4+8] = wd->sta.bssid[0]; 2940 header[4+9] = wd->sta.bssid[1]; 2941 header[4+10] = wd->sta.bssid[2]; 2942 } 2943 else if (wd->wlanMode == ZM_MODE_PSEUDO) 2944 { 2945 /* Address 3 = 00:00:00:00:00:00 */ 2946 header[4+8] = 0; 2947 header[4+9] = 0; 2948 header[4+10] = 0; 2949 } 2950 else if (wd->wlanMode == ZM_MODE_IBSS) 2951 { 2952 header[4+8] = wd->sta.bssid[0]; 2953 header[4+9] = wd->sta.bssid[1]; 2954 header[4+10] = wd->sta.bssid[2]; 2955 } 2956 else if (wd->wlanMode == ZM_MODE_AP) 2957 { 2958 /* Address 3 = BSSID */ 2959 header[4+8] = wd->macAddr[0]; 2960 header[4+9] = wd->macAddr[1]; 2961 header[4+10] = wd->macAddr[2] + (vap<<8); 2962 } 2963 2964 /* Address 1 = DA */ 2965 header[4+2] = dst[0]; 2966 header[4+3] = dst[1]; 2967 header[4+4] = dst[2]; 2968 2969 /* Address 2 = SA */ 2970 header[4+5] = wd->macAddr[0]; 2971 header[4+6] = wd->macAddr[1]; 2972 if (wd->wlanMode == ZM_MODE_AP) 2973 { 2974 header[4+7] = wd->macAddr[2] + (vap<<8); 2975 } 2976 else 2977 { 2978 header[4+7] = wd->macAddr[2]; 2979 } 2980 2981 /* Sequence Control */ 2982 zmw_enter_critical_section(dev); 2983 header[4+11] = ((wd->mmseq++)<<4); 2984 zmw_leave_critical_section(dev); 2985 2986 2987 return hlen; 2988} 2989 2990 2991u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf) 2992{ 2993 u16_t category; 2994 2995 //zmw_get_wlan_dev(dev); 2996 2997 //zmw_declare_for_critical_section(); 2998 2999 category = zmw_rx_buf_readb(dev, buf, 24); 3000 3001 switch (category) 3002 { 3003 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME: 3004 zfAggBlockAckActionFrame(dev, buf); 3005 break; 3006 3007 } 3008 3009 return ZM_SUCCESS; 3010} 3011 3012 3013u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf) 3014{ 3015 u8_t action; 3016 3017 //zmw_get_wlan_dev(dev); 3018 3019 //zmw_declare_for_critical_section(); 3020 3021 action = zmw_rx_buf_readb(dev, buf, 25); 3022#ifdef ZM_ENABLE_AGGREGATION 3023 switch (action) 3024 { 3025 case ZM_WLAN_ADDBA_REQUEST_FRAME: 3026 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request"); 3027 zfAggRecvAddbaRequest(dev, buf); 3028 break; 3029 case ZM_WLAN_ADDBA_RESPONSE_FRAME: 3030 zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response"); 3031 zfAggRecvAddbaResponse(dev, buf); 3032 break; 3033 case ZM_WLAN_DELBA_FRAME: 3034 zfAggRecvDelba(dev, buf); 3035 break; 3036 } 3037#endif 3038 return ZM_SUCCESS; 3039} 3040 3041u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf) 3042{ 3043 //u16_t dialog; 3044 struct aggBaFrameParameter bf; 3045 u16_t i; 3046 //zmw_get_wlan_dev(dev); 3047 3048 //zmw_declare_for_critical_section(); 3049 3050 bf.buf = buf; 3051 bf.dialog = zmw_rx_buf_readb(dev, buf, 26); 3052 /* 3053 * ba parameter set 3054 */ 3055 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27); 3056 bf.ba_policy = (bf.ba_parameter >> 1) & 1; 3057 bf.tid = (bf.ba_parameter >> 2) & 0xF; 3058 bf.buffer_size = (bf.ba_parameter >> 6); 3059 /* 3060 * BA timeout value 3061 */ 3062 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29); 3063 /* 3064 * BA starting sequence number 3065 */ 3066 bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4; 3067 3068 i=26; 3069 while(i < 32) { 3070 zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i)); 3071 i++; 3072 } 3073 3074 zfAggSendAddbaResponse(dev, &bf); 3075 3076 zfAggAddbaSetTidRx(dev, buf, &bf); 3077 3078 return ZM_SUCCESS; 3079} 3080 3081u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf) 3082{ 3083 u16_t i, ac, aid, fragOff; 3084 u16_t src[3]; 3085 u16_t offset = 0; 3086 u8_t up; 3087 struct agg_tid_rx *tid_rx = NULL; 3088 3089 zmw_get_wlan_dev(dev); 3090 3091 zmw_declare_for_critical_section(); 3092 3093 src[0] = zmw_rx_buf_readh(dev, buf, offset+10); 3094 src[1] = zmw_rx_buf_readh(dev, buf, offset+12); 3095 src[2] = zmw_rx_buf_readh(dev, buf, offset+14); 3096 aid = zfApFindSta(dev, src); 3097 3098 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); 3099 ac = zcUpToAc[up&0x7] & 0x3; 3100 3101 ac = bf->tid; 3102 3103 for (i=0; i<ZM_AGG_POOL_SIZE ; i++) 3104 { 3105 if((wd->tid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac)) 3106 { 3107 tid_rx = wd->tid_rx[i]; 3108 break; 3109 } 3110 } 3111 3112 if (!tid_rx) 3113 { 3114 for (i=0; i<ZM_AGG_POOL_SIZE; i++) 3115 { 3116 if (wd->tid_rx[i]->aid == ZM_MAX_STA_SUPPORT) 3117 { 3118 tid_rx = wd->tid_rx[i]; 3119 break; 3120 } 3121 } 3122 if (!tid_rx) 3123 return 0; 3124 } 3125 3126 zmw_enter_critical_section(dev); 3127 3128 tid_rx->aid = aid; 3129 tid_rx->ac = ac; 3130 tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE; 3131 tid_rx->seq_start = bf->ba_start_seq; 3132 tid_rx->baw_head = tid_rx->baw_tail = 0; 3133 tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0; 3134 zmw_leave_critical_section(dev); 3135 3136 return 0; 3137} 3138 3139u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf) 3140{ 3141 u16_t i,ac, aid=0; 3142 u16_t src[3]; 3143 struct aggBaFrameParameter bf; 3144 3145 zmw_get_wlan_dev(dev); 3146 3147 //zmw_declare_for_critical_section(); 3148 3149 src[0] = zmw_rx_buf_readh(dev, buf, 10); 3150 src[1] = zmw_rx_buf_readh(dev, buf, 12); 3151 src[2] = zmw_rx_buf_readh(dev, buf, 14); 3152 3153 if (wd->wlanMode == ZM_MODE_AP) 3154 aid = zfApFindSta(dev, src); 3155 3156 3157 bf.buf = buf; 3158 bf.dialog = zmw_rx_buf_readb(dev, buf, 26); 3159 bf.status_code = zmw_rx_buf_readh(dev, buf, 27); 3160 if (!bf.status_code) 3161 { 3162 wd->addbaComplete=1; 3163 } 3164 3165 /* 3166 * ba parameter set 3167 */ 3168 bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29); 3169 bf.ba_policy = (bf.ba_parameter >> 1) & 1; 3170 bf.tid = (bf.ba_parameter >> 2) & 0xF; 3171 bf.buffer_size = (bf.ba_parameter >> 6); 3172 /* 3173 * BA timeout value 3174 */ 3175 bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31); 3176 3177 i=26; 3178 while(i < 32) { 3179 zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i)); 3180 i++; 3181 } 3182 3183 ac = zcUpToAc[bf.tid&0x7] & 0x3; 3184 3185 //zmw_enter_critical_section(dev); 3186 3187 //wd->aggSta[aid].aggFlag[ac] = 0; 3188 3189 //zmw_leave_critical_section(dev); 3190 3191 return ZM_SUCCESS; 3192} 3193 3194u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf) 3195{ 3196 //zmw_get_wlan_dev(dev); 3197 3198 //zmw_declare_for_critical_section(); 3199 return ZM_SUCCESS; 3200} 3201 3202u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf) 3203{ 3204 zbuf_t* buf; 3205 //u16_t addrTblSize; 3206 //struct zsAddrTbl addrTbl; 3207 //u16_t err; 3208 u16_t offset = 0; 3209 u16_t hlen = 32; 3210 u16_t header[(24+25+1)/2]; 3211 u16_t vap = 0; 3212 u16_t i; 3213 u8_t encrypt = 0; 3214 u16_t dst[3]; 3215 3216 //zmw_get_wlan_dev(dev); 3217 3218 //zmw_declare_for_critical_section(); 3219 3220 3221 /* 3222 * TBD : Maximum size of management frame 3223 */ 3224 buf = zfwBufAllocate(dev, 1024); 3225 if (buf == NULL) 3226 { 3227 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); 3228 return ZM_SUCCESS; 3229 } 3230 3231 /* 3232 * Reserve room for wlan header 3233 */ 3234 offset = hlen; 3235 3236 /* 3237 * add addba frame body 3238 */ 3239 offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset); 3240 3241 3242 zfwBufSetSize(dev, buf, offset); 3243 3244 /* 3245 * Copy wlan header 3246 */ 3247 3248 dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10); 3249 dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12); 3250 dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14); 3251 zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt); 3252 for (i=0; i<(hlen>>1); i++) 3253 { 3254 zmw_tx_buf_writeh(dev, buf, i*2, header[i]); 3255 } 3256 3257 /* Get buffer DMA address */ 3258 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) 3259 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) 3260 //{ 3261 // goto zlError; 3262 //} 3263 3264 //zm_msg2_mm(ZM_LV_2, "offset=", offset); 3265 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen); 3266 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); 3267 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); 3268 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); 3269 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); 3270 3271 zfPutVmmq(dev, buf); 3272 zfPushVtxq(dev); 3273 3274 //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid); 3275 return ZM_SUCCESS; 3276 3277} 3278 3279u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf, 3280 struct aggBaFrameParameter *bf, u16_t offset) 3281{ 3282 3283 //zmw_get_wlan_dev(dev); 3284 3285 //zmw_declare_for_critical_section(); 3286 /* 3287 * ADDBA Request frame body 3288 */ 3289 3290 /* 3291 * Category 3292 */ 3293 zmw_tx_buf_writeb(dev, buf, offset++, 3); 3294 /* 3295 * Action details = 0 3296 */ 3297 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME); 3298 /* 3299 * Dialog Token = nonzero 3300 */ 3301 zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog); 3302 /* 3303 * Status code 3304 */ 3305 zmw_tx_buf_writeh(dev, buf, offset, 0); 3306 offset+=2; 3307 /* 3308 * Block Ack parameter set 3309 * BA policy = 1 for immediate BA, 0 for delayed BA 3310 * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80) 3311 * TBD: how to get TID number and buffer size? 3312 * �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�{ 3313 * �x B0 �x B1 �x B2 B5 �x B6 B15 �x 3314 * �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 3315 * �x Reserved �x BA policy �x TID �x Buffer size �x 3316 * �|�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�} 3317 */ 3318 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter); 3319 offset+=2; 3320 /* 3321 * BA timeout value 3322 */ 3323 zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout); 3324 offset+=2; 3325 3326 return offset; 3327} 3328 3329void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx) 3330{ 3331 struct aggBarControl aggBarControl; 3332 //zmw_get_wlan_dev(dev); 3333 3334 //zmw_declare_for_critical_section(); 3335 //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2 3336 // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy; 3337 aggBarControl.bar_ack_policy = 0; 3338 aggBarControl.multi_tid = 0; 3339 aggBarControl.compressed_bitmap = 0; 3340 aggBarControl.tid_info = tid_tx->tid; 3341 zfAggSendBar(dev, tid_tx, &aggBarControl); 3342 3343 return; 3344 3345} 3346/* 3347 * zfAggSendBar() refers zfAggSendAddbaRequest() 3348 */ 3349u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl) 3350{ 3351 zbuf_t* buf; 3352 //u16_t addrTblSize; 3353 //struct zsAddrTbl addrTbl; 3354 //u16_t err; 3355 u16_t offset = 0; 3356 u16_t hlen = 16+8; /* mac header + control headers*/ 3357 u16_t header[(8+24+1)/2]; 3358 u16_t vap = 0; 3359 u16_t i; 3360 u8_t encrypt = 0; 3361 3362 //zmw_get_wlan_dev(dev); 3363 3364 //zmw_declare_for_critical_section(); 3365 3366 3367 /* 3368 * TBD : Maximum size of management frame 3369 */ 3370 buf = zfwBufAllocate(dev, 1024); 3371 if (buf == NULL) 3372 { 3373 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); 3374 return ZM_SUCCESS; 3375 } 3376 3377 /* 3378 * Reserve room for wlan header 3379 */ 3380 offset = hlen; 3381 3382 /* 3383 * add addba frame body 3384 */ 3385 offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl); 3386 3387 3388 zfwBufSetSize(dev, buf, offset); 3389 3390 /* 3391 * Copy wlan header 3392 */ 3393 zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt); 3394 for (i=0; i<(hlen>>1); i++) 3395 { 3396 zmw_tx_buf_writeh(dev, buf, i*2, header[i]); 3397 } 3398 3399 /* Get buffer DMA address */ 3400 //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) 3401 //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) 3402 //{ 3403 // goto zlError; 3404 //} 3405 3406 //zm_msg2_mm(ZM_LV_2, "offset=", offset); 3407 //zm_msg2_mm(ZM_LV_2, "hlen=", hlen); 3408 //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); 3409 //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); 3410 //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); 3411 //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); 3412 3413 zfPutVmmq(dev, buf); 3414 zfPushVtxq(dev); 3415 3416 return ZM_SUCCESS; 3417 3418} 3419 3420u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl) 3421{ 3422 u16_t bar_control, start_seq; 3423 3424 //zmw_get_wlan_dev(dev); 3425 3426 //zmw_declare_for_critical_section(); 3427 /* 3428 * BAR Control frame body 3429 */ 3430 3431 /* 3432 * BAR Control Field 3433 * �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�{ 3434 * �x B0 �x B1 �x B2 �x B3 B11 �x B12 B15 �x 3435 * �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 3436 * �x BAR Ack �x Multi-TID �x Compressed �x Reserved �x TID_INFO �x 3437 * �x Policy �x �x Bitmap �x �x �x 3438 * �|�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�} 3439 */ 3440 bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2 3441 | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy; 3442 3443 zmw_tx_buf_writeh(dev, buf, offset, bar_control); 3444 offset+=2; 3445 if (0 == aggBarControl->multi_tid) { 3446 /* 3447 * BA starting sequence number 3448 * �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�{ 3449 * �x B0 B3 �x B4 B15 �x 3450 * �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 3451 * �x Frag num(0) �x BA starting seq num �x 3452 * �|�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�} 3453 */ 3454 start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0; 3455 zmw_tx_buf_writeh(dev, buf, offset, start_seq); 3456 offset+=2; 3457 } 3458 if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) { 3459 /* multi-tid BlockAckReq variant, not implemented*/ 3460 } 3461 3462 return offset; 3463} 3464 3465u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst, 3466 u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt) 3467{ 3468 u8_t hlen = 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header 3469 //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION; 3470 3471 zmw_get_wlan_dev(dev); 3472 3473 zmw_declare_for_critical_section(); 3474 3475 /* 3476 * Generate control setting 3477 */ 3478 //bodyLen = zfwBufGetSize(dev, buf); 3479 header[0] = 16+len+4; //Length 3480 header[1] = 0x8; //MAC control, backoff + (ack) 3481 3482 /* CCK 1M */ 3483 header[2] = 0x0f00; //PHY control L 3484 header[3] = 0x0000; //PHY control H 3485 /* 3486 * Generate WLAN header 3487 * Frame control frame type and subtype 3488 */ 3489 header[4+0] = ZM_WLAN_FRAME_TYPE_BAR; 3490 /* 3491 * Duration 3492 */ 3493 header[4+1] = 0; 3494 3495 /* Address 1 = DA */ 3496 header[4+2] = dst[0]; 3497 header[4+3] = dst[1]; 3498 header[4+4] = dst[2]; 3499 3500 /* Address 2 = SA */ 3501 header[4+5] = wd->macAddr[0]; 3502 header[4+6] = wd->macAddr[1]; 3503 if (wd->wlanMode == ZM_MODE_AP) 3504 { 3505#ifdef ZM_VAPMODE_MULTILE_SSID 3506 header[4+7] = wd->macAddr[2]; //Multiple SSID 3507#else 3508 header[4+7] = wd->macAddr[2] + (vap<<8); //VAP 3509#endif 3510 } 3511 else 3512 { 3513 header[4+7] = wd->macAddr[2]; 3514 } 3515 3516 /* Sequence Control */ 3517 zmw_enter_critical_section(dev); 3518 header[4+11] = ((wd->mmseq++)<<4); 3519 zmw_leave_critical_section(dev); 3520 3521 3522 return hlen; 3523} 3524