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 : mm.c */ 18/* */ 19/* Abstract */ 20/* This module contains common functions for handle AP */ 21/* management frame. */ 22/* */ 23/* NOTES */ 24/* None */ 25/* */ 26/************************************************************************/ 27#include "cprecomp.h" 28#include "ratectrl.h" 29 30extern const u8_t zcUpToAc[]; 31 32void zfMmApTimeTick(zdev_t* dev) 33{ 34 u32_t now; 35 zmw_get_wlan_dev(dev); 36 37 //zm_debug_msg1("wd->wlanMode : ", wd->wlanMode); 38 if (wd->wlanMode == ZM_MODE_AP) 39 { 40 /* => every 1.28 seconds */ 41 /* AP : aging STA that does not active for wd->ap.staAgingTime */ 42 now = wd->tick & 0x7f; 43 if (now == 0x0) 44 { 45 zfApAgingSta(dev); 46 } 47 else if (now == 0x1f) 48 { 49 zfQueueAge(dev, wd->ap.uapsdQ, wd->tick, 10000); 50 } 51 /* AP : check (wd->ap.protectedObss) and (wd->ap.bStaAssociated) */ 52 /* to enable NonErp and Protection mode */ 53 else if (now == 0x3f) 54 { 55 //zfApProtctionMonitor(dev); 56 } 57 } 58} 59 60/************************************************************************/ 61/* */ 62/* FUNCTION DESCRIPTION zfApInitStaTbl */ 63/* Init AP's station table. */ 64/* */ 65/* INPUTS */ 66/* dev : device pointer */ 67/* */ 68/* OUTPUTS */ 69/* None */ 70/* */ 71/* AUTHOR */ 72/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ 73/* */ 74/************************************************************************/ 75void zfApInitStaTbl(zdev_t* dev) 76{ 77 u16_t i; 78 79 zmw_get_wlan_dev(dev); 80 81 for (i=0; i<ZM_MAX_STA_SUPPORT; i++) 82 { 83 wd->ap.staTable[i].valid = 0; 84 wd->ap.staTable[i].state = 0; 85 wd->ap.staTable[i].addr[0] = 0; 86 wd->ap.staTable[i].addr[1] = 0; 87 wd->ap.staTable[i].addr[2] = 0; 88 wd->ap.staTable[i].time = 0; 89 wd->ap.staTable[i].vap = 0; 90 wd->ap.staTable[i].encryMode = ZM_NO_WEP; 91 } 92 return; 93} 94 95 96/************************************************************************/ 97/* */ 98/* FUNCTION DESCRIPTION zfApFindSta */ 99/* Find a STA in station table. */ 100/* */ 101/* INPUTS */ 102/* dev : device pointer */ 103/* addr : Target STA address */ 104/* */ 105/* OUTPUTS */ 106/* 0xffff : fail */ 107/* other : STA table index */ 108/* */ 109/* AUTHOR */ 110/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ 111/* */ 112/************************************************************************/ 113u16_t zfApFindSta(zdev_t* dev, u16_t* addr) 114{ 115 u16_t i; 116 117 zmw_get_wlan_dev(dev); 118 119 for (i=0; i<ZM_MAX_STA_SUPPORT; i++) 120 { 121 if (wd->ap.staTable[i].valid == 1) 122 { 123 if ((wd->ap.staTable[i].addr[0] == addr[0]) 124 && (wd->ap.staTable[i].addr[1] == addr[1]) 125 && (wd->ap.staTable[i].addr[2] == addr[2])) 126 { 127 return i; 128 } 129 } 130 } 131 return 0xffff; 132} 133 134u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap) 135{ 136 u16_t id; 137 138 zmw_get_wlan_dev(dev); 139 140 zmw_declare_for_critical_section(); 141 142 zmw_enter_critical_section(dev); 143 144 id = zfApFindSta(dev, addr); 145 if (id != 0xffff) 146 { 147 *vap = wd->ap.staTable[id].vap; 148 *state = wd->ap.staTable[id++].state; 149 } 150 151 zmw_leave_critical_section(dev); 152 153 return id; 154} 155 156 157void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType) 158{ 159 u16_t id; 160 161 zmw_get_wlan_dev(dev); 162 163 zmw_declare_for_critical_section(); 164 165 zmw_enter_critical_section(dev); 166 167 id = zfApFindSta(dev, addr); 168 if (id != 0xffff) 169 { 170 *qosType = wd->ap.staTable[id].qosType; 171 } 172 else 173 { 174 *qosType = 0; 175 } 176 177 zmw_leave_critical_section(dev); 178 179 return; 180} 181 182void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl, 183 u8_t* qosType, u16_t* rcProbingFlag) 184{ 185 u16_t id; 186 u8_t rate; 187 188 zmw_get_wlan_dev(dev); 189 190 zmw_declare_for_critical_section(); 191 192 zmw_enter_critical_section(dev); 193 194 id = zfApFindSta(dev, addr); 195 if (id != 0xffff) 196 { 197 rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag); 198#ifdef ZM_AP_DEBUG 199 //rate = 15; 200#endif 201 *phyCtrl = zcRateToPhyCtrl[rate]; 202 *qosType = wd->ap.staTable[id].qosType; 203 } 204 else 205 { 206 if (wd->frequency < 3000) 207 { 208 /* CCK 1M */ 209 //header[2] = 0x0f00; //PHY control L 210 //header[3] = 0x0000; //PHY control H 211 *phyCtrl = 0x00000F00; 212 } 213 else 214 { 215 /* CCK 6M */ 216 //header[2] = 0x0f01; //PHY control L 217 //header[3] = 0x000B; //PHY control H 218 *phyCtrl = 0x000B0F01; 219 } 220 *qosType = 0; 221 } 222 223 zmw_leave_critical_section(dev); 224 225 zm_msg2_mm(ZM_LV_3, "PhyCtrl=", *phyCtrl); 226 return; 227} 228 229void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType) 230{ 231 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); 232 u16_t id; 233 234 zmw_get_wlan_dev(dev); 235 236 zmw_declare_for_critical_section(); 237 238 zmw_enter_critical_section(dev); 239 240 id = zfApFindSta(dev, addr); 241 if (id != 0xffff) 242 { 243 *encryType = wd->ap.staTable[id].encryMode; 244 } 245 else 246 { 247 *encryType = ZM_NO_WEP; 248 } 249 250 zmw_leave_critical_section(dev); 251 252 zm_msg2_mm(ZM_LV_3, "encyrType=", *encryType); 253 return; 254} 255 256void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32) 257{ 258 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); 259 u16_t id; 260 261 zmw_get_wlan_dev(dev); 262 263 zmw_declare_for_critical_section(); 264 265 zmw_enter_critical_section(dev); 266 267 id = zfApFindSta(dev, addr); 268 if (id != 0xffff) 269 { 270 *iv16 = wd->ap.staTable[id].iv16; 271 *iv32 = wd->ap.staTable[id].iv32; 272 } 273 else 274 { 275 *iv16 = 0; 276 *iv32 = 0; 277 } 278 279 zmw_leave_critical_section(dev); 280 281 zm_msg2_mm(ZM_LV_3, "iv16=", *iv16); 282 zm_msg2_mm(ZM_LV_3, "iv32=", *iv32); 283 return; 284} 285 286void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32) 287{ 288 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); 289 u16_t id; 290 291 zmw_get_wlan_dev(dev); 292 293 zmw_declare_for_critical_section(); 294 295 zmw_enter_critical_section(dev); 296 297 id = zfApFindSta(dev, addr); 298 if (id != 0xffff) 299 { 300 wd->ap.staTable[id].iv16 = iv16; 301 wd->ap.staTable[id].iv32 = iv32; 302 } 303 304 zmw_leave_critical_section(dev); 305 306 zm_msg2_mm(ZM_LV_3, "iv16=", iv16); 307 zm_msg2_mm(ZM_LV_3, "iv32=", iv32); 308 return; 309} 310 311void zfApClearStaKey(zdev_t* dev, u16_t* addr) 312{ 313 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); 314 u16_t bcAddr[3] = { 0xffff, 0xffff, 0xffff }; 315 u16_t id; 316 317 zmw_get_wlan_dev(dev); 318 319 if (zfMemoryIsEqual((u8_t*)bcAddr, (u8_t*)addr, sizeof(bcAddr)) == TRUE) 320 { 321 /* Turn off group key information */ 322 // zfClearKey(dev, 0); 323 } 324 else 325 { 326 zmw_declare_for_critical_section(); 327 328 zmw_enter_critical_section(dev); 329 330 id = zfApFindSta(dev, addr); 331 if (id != 0xffff) 332 { 333 /* Turn off STA's key information */ 334 zfHpRemoveKey(dev, id+1); 335 336 /* Update STA's Encryption Type */ 337 wd->ap.staTable[id].encryMode = ZM_NO_WEP; 338 } 339 else 340 { 341 zm_msg0_mm(ZM_LV_3, "Can't find STA address\n"); 342 } 343 zmw_leave_critical_section(dev); 344 } 345} 346 347#ifdef ZM_ENABLE_CENC 348void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, u8_t *keyIdx) 349{ 350 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); 351 u16_t id; 352 zmw_get_wlan_dev(dev); 353 zmw_declare_for_critical_section(); 354 355 356 zmw_enter_critical_section(dev); 357 358 id = zfApFindSta(dev, addr); 359 if (id != 0xffff) 360 { 361 *iv++ = wd->ap.staTable[id].txiv[0]; 362 *iv++ = wd->ap.staTable[id].txiv[1]; 363 *iv++ = wd->ap.staTable[id].txiv[2]; 364 *iv = wd->ap.staTable[id].txiv[3]; 365 *keyIdx = wd->ap.staTable[id].cencKeyIdx; 366 } 367 else 368 { 369 *iv++ = 0x5c365c37; 370 *iv++ = 0x5c365c36; 371 *iv++ = 0x5c365c36; 372 *iv = 0x5c365c36; 373 *keyIdx = 0; 374 } 375 376 zmw_leave_critical_section(dev); 377 return; 378} 379 380void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv) 381{ 382 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); 383 u16_t id; 384 zmw_get_wlan_dev(dev); 385 zmw_declare_for_critical_section(); 386 387 388 zmw_enter_critical_section(dev); 389 390 id = zfApFindSta(dev, addr); 391 if (id != 0xffff) 392 { 393 wd->ap.staTable[id].txiv[0] = *iv++; 394 wd->ap.staTable[id].txiv[1] = *iv++; 395 wd->ap.staTable[id].txiv[2] = *iv++; 396 wd->ap.staTable[id].txiv[3] = *iv; 397 } 398 399 zmw_leave_critical_section(dev); 400 401 return; 402} 403#endif //ZM_ENABLE_CENC 404 405 406/************************************************************************/ 407/* */ 408/* FUNCTION DESCRIPTION zfApFlushBufferedPsFrame */ 409/* Free buffered PS frames. */ 410/* */ 411/* INPUTS */ 412/* dev : device pointer */ 413/* */ 414/* OUTPUTS */ 415/* None */ 416/* */ 417/* AUTHOR */ 418/* Stephen Chen Atheros Communications, INC. 2007.1 */ 419/* */ 420/************************************************************************/ 421void zfApFlushBufferedPsFrame(zdev_t* dev) 422{ 423 u16_t emptyFlag; 424 u16_t freeCount; 425 u16_t vap; 426 zbuf_t* psBuf = NULL; 427 zmw_get_wlan_dev(dev); 428 zmw_declare_for_critical_section(); 429 430 freeCount = 0; 431 emptyFlag = 0; 432 while (1) 433 { 434 psBuf = NULL; 435 zmw_enter_critical_section(dev); 436 if (wd->ap.uniHead != wd->ap.uniTail) 437 { 438 psBuf = wd->ap.uniArray[wd->ap.uniHead]; 439 wd->ap.uniHead = (wd->ap.uniHead + 1) & (ZM_UNI_ARRAY_SIZE - 1); 440 } 441 else 442 { 443 emptyFlag = 1; 444 } 445 zmw_leave_critical_section(dev); 446 447 if (psBuf != NULL) 448 { 449 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE); 450 } 451 zm_assert(freeCount++ < (ZM_UNI_ARRAY_SIZE*2)); 452 453 if (emptyFlag != 0) 454 { 455 break; 456 } 457 } 458 459 for (vap=0; vap<ZM_MAX_AP_SUPPORT; vap++) 460 { 461 freeCount = 0; 462 emptyFlag = 0; 463 while (1) 464 { 465 psBuf = NULL; 466 zmw_enter_critical_section(dev); 467 if (wd->ap.bcmcHead[vap] != wd->ap.bcmcTail[vap]) 468 { 469 psBuf = wd->ap.bcmcArray[vap][wd->ap.bcmcHead[vap]]; 470 wd->ap.bcmcHead[vap] = (wd->ap.bcmcHead[vap] + 1) 471 & (ZM_BCMC_ARRAY_SIZE - 1); 472 } 473 else 474 { 475 emptyFlag = 1; 476 } 477 zmw_leave_critical_section(dev); 478 479 if (psBuf != NULL) 480 { 481 zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE); 482 } 483 zm_assert(freeCount++ < (ZM_BCMC_ARRAY_SIZE*2)); 484 485 if (emptyFlag != 0) 486 { 487 break; 488 } 489 } 490 } 491 return; 492} 493 494 495u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port) 496{ 497 u16_t id; 498 u16_t addr[3]; 499 u16_t vap = 0; 500 u8_t up; 501 u16_t fragOff; 502 u8_t ac; 503 u16_t ret; 504 505 zmw_get_wlan_dev(dev); 506 507 zmw_declare_for_critical_section(); 508 509 if (port < ZM_MAX_AP_SUPPORT) 510 { 511 vap = port; 512 } 513 514 addr[0] = zmw_rx_buf_readh(dev, buf, 0); 515 addr[1] = zmw_rx_buf_readh(dev, buf, 2); 516 addr[2] = zmw_rx_buf_readh(dev, buf, 4); 517 518 if ((addr[0] & 0x1) == 0x1) 519 { 520 if (wd->ap.staPowerSaving > 0) 521 { 522 zmw_enter_critical_section(dev); 523 524 /* Buffer this BC or MC frame */ 525 if (((wd->ap.bcmcTail[vap]+1)&(ZM_BCMC_ARRAY_SIZE-1)) 526 != wd->ap.bcmcHead[vap]) 527 { 528 wd->ap.bcmcArray[vap][wd->ap.bcmcTail[vap]++] = buf; 529 wd->ap.bcmcTail[vap] &= (ZM_BCMC_ARRAY_SIZE-1); 530 zmw_leave_critical_section(dev); 531 532 zm_msg0_tx(ZM_LV_0, "Buffer BCMC"); 533 } 534 else 535 { 536 /* bcmcArray full */ 537 zmw_leave_critical_section(dev); 538 539 zm_msg0_tx(ZM_LV_0, "BCMC buffer full"); 540 541 /* free buffer according to buffer type */ 542 zfwBufFree(dev, buf, ZM_ERR_BCMC_PS_BUFFER_UNAVAILABLE); 543 } 544 return 1; 545 } 546 } 547 else 548 { 549 zmw_enter_critical_section(dev); 550 551 id = zfApFindSta(dev, addr); 552 if (id != 0xffff) 553 { 554 if (wd->ap.staTable[id].psMode == 1) 555 { 556 557 zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); 558 ac = zcUpToAc[up&0x7] & 0x3; 559 560 if ((wd->ap.staTable[id].qosType == 1) && 561 ((wd->ap.staTable[id].qosInfo & (0x8>>ac)) != 0)) 562 { 563 ret = zfQueuePutNcs(dev, wd->ap.uapsdQ, buf, wd->tick); 564 zmw_leave_critical_section(dev); 565 if (ret != ZM_SUCCESS) 566 { 567 zfwBufFree(dev, buf, ZM_ERR_AP_UAPSD_QUEUE_FULL); 568 } 569 } 570 else 571 { 572 /* Buffer this unicast frame */ 573 if (((wd->ap.uniTail+1)&(ZM_UNI_ARRAY_SIZE-1)) 574 != wd->ap.uniHead) 575 { 576 wd->ap.uniArray[wd->ap.uniTail++] = buf; 577 wd->ap.uniTail &= (ZM_UNI_ARRAY_SIZE-1); 578 zmw_leave_critical_section(dev); 579 zm_msg0_tx(ZM_LV_0, "Buffer UNI"); 580 581 } 582 else 583 { 584 /* uniArray full */ 585 zmw_leave_critical_section(dev); 586 zm_msg0_tx(ZM_LV_0, "UNI buffer full"); 587 /* free buffer according to buffer type */ 588 zfwBufFree(dev, buf, ZM_ERR_UNI_PS_BUFFER_UNAVAILABLE); 589 } 590 } 591 return 1; 592 } /* if (wd->ap.staTable[id++].psMode == 1) */ 593 } /* if ((id = zfApFindSta(dev, addr)) != 0xffff) */ 594 zmw_leave_critical_section(dev); 595 } 596 597 return 0; 598} 599 600u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state, 601 u8_t* vap, u16_t psMode, u8_t* uapsdTrig) 602{ 603 u16_t id; 604 u8_t uapsdStaAwake = 0; 605 606 zmw_get_wlan_dev(dev); 607 608 zmw_declare_for_critical_section(); 609 610 zmw_enter_critical_section(dev); 611 612#ifdef ZM_AP_DEBUG 613 //psMode=0; 614#endif 615 616 id = zfApFindSta(dev, addr); 617 if (id != 0xffff) 618 { 619 if (psMode != 0) 620 { 621 zm_msg0_mm(ZM_LV_0, "psMode = 1"); 622 if (wd->ap.staTable[id].psMode == 0) 623 { 624 wd->ap.staPowerSaving++; 625 } 626 else 627 { 628 if (wd->ap.staTable[id].qosType == 1) 629 { 630 zm_msg0_mm(ZM_LV_0, "UAPSD trigger"); 631 *uapsdTrig = wd->ap.staTable[id].qosInfo; 632 } 633 } 634 } 635 else 636 { 637 if (wd->ap.staTable[id].psMode != 0) 638 { 639 wd->ap.staPowerSaving--; 640 if ((wd->ap.staTable[id].qosType == 1) && ((wd->ap.staTable[id].qosInfo&0xf)!=0)) 641 { 642 uapsdStaAwake = 1; 643 } 644 } 645 } 646 647 wd->ap.staTable[id].psMode = (u8_t) psMode; 648 wd->ap.staTable[id].time = wd->tick; 649 *vap = wd->ap.staTable[id].vap; 650 *state = wd->ap.staTable[id++].state; 651 } 652 653 zmw_leave_critical_section(dev); 654 655 if (uapsdStaAwake == 1) 656 { 657 zbuf_t* psBuf; 658 u8_t mb; 659 660 while (1) 661 { 662 psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb); 663 if (psBuf != NULL) 664 { 665 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); 666 } 667 else 668 { 669 break; 670 } 671 } 672 } 673 674 return id; 675} 676 677/************************************************************************/ 678/* */ 679/* FUNCTION DESCRIPTION zfApGetNewSta */ 680/* Get a new STA from station table. */ 681/* */ 682/* INPUTS */ 683/* dev : device pointer */ 684/* */ 685/* OUTPUTS */ 686/* 0xffff : fail */ 687/* other : STA table index */ 688/* */ 689/* AUTHOR */ 690/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ 691/* */ 692/************************************************************************/ 693u16_t zfApGetNewSta(zdev_t* dev) 694{ 695 u16_t i; 696 697 zmw_get_wlan_dev(dev); 698 699 for (i=0; i<ZM_MAX_STA_SUPPORT; i++) 700 { 701 if (wd->ap.staTable[i].valid == 0) 702 { 703 zm_msg2_mm(ZM_LV_0, "zfApGetNewSta=", i); 704 return i; 705 } 706 } 707 return 0xffff; 708} 709 710 711/************************************************************************/ 712/* */ 713/* FUNCTION DESCRIPTION zfApAddSta */ 714/* Add a STA to station table. */ 715/* */ 716/* INPUTS */ 717/* dev : device pointer */ 718/* addr : STA MAC address */ 719/* state : STA state */ 720/* apId : Virtual AP ID */ 721/* type : 0=>11b, 1=>11g */ 722/* */ 723/* OUTPUTS */ 724/* 0xffff : fail */ 725/* Other : index */ 726/* */ 727/* AUTHOR */ 728/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ 729/* */ 730/************************************************************************/ 731u16_t zfApAddSta(zdev_t* dev, u16_t* addr, u16_t state, u16_t apId, u8_t type, 732 u8_t qosType, u8_t qosInfo) 733{ 734 u16_t index; 735 u16_t i; 736 737 zmw_get_wlan_dev(dev); 738 739 zmw_declare_for_critical_section(); 740 741 zm_msg1_mm(ZM_LV_0, "STA type=", type); 742 743 zmw_enter_critical_section(dev); 744 745 index = zfApFindSta(dev, addr); 746 if (index != 0xffff) 747 { 748 zm_msg0_mm(ZM_LV_2, "found"); 749 /* Update STA state */ 750 if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH)) 751 { 752 wd->ap.staTable[index].state = state; 753 wd->ap.staTable[index].time = wd->tick; 754 wd->ap.staTable[index].vap = (u8_t)apId; 755 } 756 else if (state == ZM_STATE_ASOC) 757 { 758 if ((wd->ap.staTable[index].state == ZM_STATE_AUTH)) 759 //&& (wd->ap.staTable[index].vap == apId)) 760 { 761 wd->ap.staTable[index].state = state; 762 wd->ap.staTable[index].time = wd->tick; 763 wd->ap.staTable[index].qosType = qosType; 764 wd->ap.staTable[index].vap = (u8_t)apId; 765 wd->ap.staTable[index].staType = type; 766 wd->ap.staTable[index].qosInfo = qosInfo; 767 768 if (wd->frequency < 3000) 769 { 770 /* Init 11b/g */ 771 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 1, 1); 772 } 773 else 774 { 775 /* Init 11a */ 776 zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 0, 1); 777 } 778 779 if (wd->zfcbApConnectNotify != NULL) 780 { 781 wd->zfcbApConnectNotify(dev, (u8_t*)addr, apId); 782 } 783 } 784 else 785 { 786 index = 0xffff; 787 } 788 } 789 } 790 else 791 { 792 zm_msg0_mm(ZM_LV_2, "Not found"); 793 if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH)) 794 { 795 /* Get a new STA and update state */ 796 index = zfApGetNewSta(dev); 797 zm_msg2_mm(ZM_LV_1, "new STA index=", index); 798 799 if (index != 0xffff) 800 { 801 for (i=0; i<3; i++) 802 { 803 wd->ap.staTable[index].addr[i] = addr[i]; 804 } 805 wd->ap.staTable[index].state = state; 806 wd->ap.staTable[index].valid = 1; 807 wd->ap.staTable[index].time = wd->tick; 808 wd->ap.staTable[index].vap = (u8_t)apId; 809 wd->ap.staTable[index].encryMode = ZM_NO_WEP; 810 } 811 } 812 } 813 814 zmw_leave_critical_section(dev); 815 816 return index; 817} 818 819 820/************************************************************************/ 821/* */ 822/* FUNCTION DESCRIPTION zfApAgingSta */ 823/* Aging STA in station table. */ 824/* */ 825/* INPUTS */ 826/* dev : device pointer */ 827/* */ 828/* OUTPUTS */ 829/* number of 11b STA in STA table */ 830/* */ 831/* AUTHOR */ 832/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ 833/* */ 834/************************************************************************/ 835void zfApAgingSta(zdev_t* dev) 836{ 837 u16_t i; 838 u32_t deltaMs; 839 u16_t addr[3]; 840 u16_t txFlag; 841 u16_t psStaCount = 0; 842 843 zmw_get_wlan_dev(dev); 844 845 zmw_declare_for_critical_section(); 846 847 wd->ap.gStaAssociated = wd->ap.bStaAssociated = 0; 848 849 for (i=0; i<ZM_MAX_STA_SUPPORT; i++) 850 { 851 txFlag = 0; 852 zmw_enter_critical_section(dev); 853 if (wd->ap.staTable[i].valid == 1) 854 { 855 addr[0] = wd->ap.staTable[i].addr[0]; 856 addr[1] = wd->ap.staTable[i].addr[1]; 857 addr[2] = wd->ap.staTable[i].addr[2]; 858 /* millisecond */ 859 deltaMs = (u32_t)((u32_t)wd->tick-(u32_t)wd->ap.staTable[i].time) 860 * ZM_MS_PER_TICK; 861 862 /* preauth */ 863 if ((wd->ap.staTable[i].state == ZM_STATE_PREAUTH) 864 && (deltaMs > ZM_PREAUTH_TIMEOUT_MS)) 865 { 866 /* Aging STA */ 867 wd->ap.staTable[i].valid = 0; 868 wd->ap.authSharing = 0; 869 txFlag = 1; 870 } 871 872 /* auth */ 873 if ((wd->ap.staTable[i].state == ZM_STATE_AUTH) 874 && (deltaMs > ZM_AUTH_TIMEOUT_MS)) 875 { 876 /* Aging STA */ 877 wd->ap.staTable[i].valid = 0; 878 txFlag = 1; 879 } 880 881 /* asoc */ 882 if (wd->ap.staTable[i].state == ZM_STATE_ASOC) 883 { 884 if (wd->ap.staTable[i].psMode != 0) 885 { 886 psStaCount++; 887 } 888 889 if (deltaMs > ((u32_t)wd->ap.staAgingTimeSec<<10)) 890 { 891 /* Aging STA */ 892 zm_msg1_mm(ZM_LV_0, "Age STA index=", i); 893 wd->ap.staTable[i].valid = 0; 894 txFlag = 1; 895 } 896 else if (deltaMs > ((u32_t)wd->ap.staProbingTimeSec<<10)) 897 { 898 if (wd->ap.staTable[i].psMode == 0) 899 { 900 /* Probing non-PS STA */ 901 zm_msg1_mm(ZM_LV_0, "Probing STA index=", i); 902 wd->ap.staTable[i].time += 903 (wd->ap.staProbingTimeSec * ZM_TICK_PER_SECOND); 904 txFlag = 2; 905 } 906 } 907 } 908 909 910 } 911 zmw_leave_critical_section(dev); 912 913 if (txFlag == 1) 914 { 915 /* Send deauthentication management frame */ 916 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, addr, 4, 0, 0); 917 } 918 else if (txFlag == 2) 919 { 920 zfSendMmFrame(dev, ZM_WLAN_DATA_FRAME, addr, 0, 0, 0); 921 } 922 923 } 924 925 wd->ap.staPowerSaving = psStaCount; 926 927 return; 928} 929 930void zfApProtctionMonitor(zdev_t* dev) 931{ 932 zmw_get_wlan_dev(dev); 933 934 /* 11b STA associated => nonErp, Protect */ 935 if (wd->ap.bStaAssociated > 0) 936 { 937 /* Enable NonErp bit in information element */ 938 wd->erpElement = ZM_WLAN_NON_ERP_PRESENT_BIT 939 | ZM_WLAN_USE_PROTECTION_BIT; 940 941 /* Enable protection mode */ 942 zfApSetProtectionMode(dev, 1); 943 944 } 945 /* 11b STA not associated, protection OBSS present => Protect */ 946 else if (wd->ap.protectedObss > 2) //Threshold 947 { 948 if (wd->disableSelfCts == 0) 949 { 950 /* Disable NonErp bit in information element */ 951 wd->erpElement = ZM_WLAN_USE_PROTECTION_BIT; 952 953 /* Enable protection mode */ 954 zfApSetProtectionMode(dev, 1); 955 } 956 } 957 else 958 { 959 /* Disable NonErp bit in information element */ 960 wd->erpElement = 0; 961 962 /* Disable protection mode */ 963 zfApSetProtectionMode(dev, 0); 964 } 965 wd->ap.protectedObss = 0; 966} 967 968 969void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf) 970{ 971 u16_t offset; 972 u8_t ch; 973 974 zmw_get_wlan_dev(dev); 975 976 zm_msg0_mm(ZM_LV_3, "Rx beacon"); 977 978 /* update Non-ERP flag(wd->ap.nonErpObss) */ 979 offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP); 980 if (offset == 0xffff) 981 { 982 /* 11b OBSS */ 983 wd->ap.protectedObss++; 984 return; 985 } 986 987 ch = zmw_rx_buf_readb(dev, buf, offset+2); 988 if ((ch & ZM_WLAN_USE_PROTECTION_BIT) == ZM_WLAN_USE_PROTECTION_BIT) 989 { 990 /* Protected OBSS */ 991 wd->ap.protectedObss = 1; 992 } 993 994 return; 995} 996 997 998/************************************************************************/ 999/* */ 1000/* FUNCTION DESCRIPTION zfProcessAuth */ 1001/* Process authenticate management frame. */ 1002/* */ 1003/* INPUTS */ 1004/* dev : device pointer */ 1005/* buf : auth frame buffer */ 1006/* */ 1007/* OUTPUTS */ 1008/* none */ 1009/* */ 1010/* AUTHOR */ 1011/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ 1012/* */ 1013/************************************************************************/ 1014/* Note : AP allows one authenticating STA at a time, does not */ 1015/* support multiple authentication process. Make sure */ 1016/* authentication state machine will not be blocked due */ 1017/* to incompleted authentication handshake. */ 1018void zfApProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) 1019{ 1020 u16_t algo, seq, status; 1021 u8_t authSharing; 1022 u16_t ret; 1023 u16_t i; 1024 u8_t challengePassed = 0; 1025 u8_t frameCtrl; 1026 u32_t retAlgoSeq; 1027 u32_t retStatus; 1028 zmw_get_wlan_dev(dev); 1029 zmw_declare_for_critical_section(); 1030 1031 1032 frameCtrl = zmw_rx_buf_readb(dev, buf, 1); 1033 /* AP : Auth share 3 */ 1034 /* shift for WEP IV */ 1035 if ((frameCtrl & 0x40) != 0) 1036 { 1037 algo = zmw_rx_buf_readh(dev, buf, 28); 1038 seq = zmw_rx_buf_readh(dev, buf, 30); 1039 status = zmw_rx_buf_readh(dev, buf, 32); 1040 } 1041 else 1042 { 1043 algo = zmw_rx_buf_readh(dev, buf, 24); 1044 seq = zmw_rx_buf_readh(dev, buf, 26); 1045 status = zmw_rx_buf_readh(dev, buf, 28); 1046 } 1047 1048 zm_msg2_mm(ZM_LV_0, "Rx Auth, seq=", seq); 1049 1050 /* Set default to authentication algorithm not support */ 1051 retAlgoSeq = 0x20000 | algo; 1052 retStatus = 13; /* authentication algorithm not support */ 1053 1054 /* AP : Auth open 1 */ 1055 if (algo == 0) 1056 { 1057 if (wd->ap.authAlgo[apId] == 0) 1058 { 1059 retAlgoSeq = 0x20000; 1060 if (seq == 1) 1061 { 1062 /* AP : update STA to auth */ 1063 ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0); 1064 if (ret != 0xffff) 1065 { 1066 /* AP : call zfwAuthNotify() for host to judge */ 1067 //zfwAuthNotify(dev, src); 1068 1069 /* AP : response Auth seq=2, success */ 1070 retStatus = 0; 1071 1072 } 1073 else 1074 { 1075 /* AP : response Auth seq=2, unspecific error */ 1076 retStatus = 1; 1077 } 1078 } 1079 else 1080 { 1081 /* AP : response Auth seq=2, sequence number out of expected */ 1082 retStatus = 14; 1083 } 1084 } 1085 } 1086 /* AP : Auth share 1 */ 1087 else if (algo == 1) 1088 { 1089 if (wd->ap.authAlgo[apId] == 1) 1090 { 1091 if (seq == 1) 1092 { 1093 retAlgoSeq = 0x20001; 1094 1095 /* critical section */ 1096 zmw_enter_critical_section(dev); 1097 if (wd->ap.authSharing == 1) 1098 { 1099 authSharing = 1; 1100 } 1101 else 1102 { 1103 authSharing = 0; 1104 wd->ap.authSharing = 1; 1105 } 1106 /* end of critical section */ 1107 zmw_leave_critical_section(dev); 1108 1109 if (authSharing == 1) 1110 { 1111 /* AP : response Auth seq=2, status = fail */ 1112 retStatus = 1; 1113 } 1114 else 1115 { 1116 /* AP : update STA to preauth */ 1117 zfApAddSta(dev, src, ZM_STATE_PREAUTH, apId, 0, 0, 0); 1118 1119 /* AP : call zfwAuthNotify() for host to judge */ 1120 //zfwAuthNotify(dev, src); 1121 1122 /* AP : response Auth seq=2 */ 1123 retStatus = 0; 1124 } 1125 } 1126 else if (seq == 3) 1127 { 1128 retAlgoSeq = 0x40001; 1129 1130 if (wd->ap.authSharing == 1) 1131 { 1132 /* check challenge text */ 1133 if (zmw_buf_readh(dev, buf, 30+4) == 0x8010) 1134 { 1135 for (i=0; i<128; i++) 1136 { 1137 if (wd->ap.challengeText[i] 1138 != zmw_buf_readb(dev, buf, 32+i+4)) 1139 { 1140 break; 1141 } 1142 } 1143 if (i == 128) 1144 { 1145 challengePassed = 1; 1146 } 1147 } 1148 1149 if (challengePassed == 1) 1150 { 1151 /* AP : update STA to auth */ 1152 zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0); 1153 1154 /* AP : response Auth seq=2 */ 1155 retStatus = 0; 1156 } 1157 else 1158 { 1159 /* AP : response Auth seq=2, challenge failure */ 1160 retStatus = 15; 1161 1162 /* TODO : delete STA */ 1163 } 1164 1165 wd->ap.authSharing = 0; 1166 } 1167 } 1168 else 1169 { 1170 retAlgoSeq = 0x40001; 1171 retStatus = 14; 1172 } 1173 } 1174 } 1175 1176 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, src, retAlgoSeq, 1177 retStatus, apId); 1178 return; 1179} 1180 1181void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) 1182{ 1183 u16_t aid = 0xffff; 1184 u8_t frameType; 1185 u16_t offset; 1186 u8_t staType = 0; 1187 u8_t qosType = 0; 1188 u8_t qosInfo = 0; 1189 u8_t tmp; 1190 u16_t i, j, k; 1191 u16_t encMode = 0; 1192 1193 zmw_get_wlan_dev(dev); 1194 /* AP : check SSID */ 1195 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID); 1196 if (offset != 0xffff) 1197 { 1198 k = 0; 1199 for (j = 0; j < wd->ap.vapNumber; j++) 1200 { 1201 tmp = zmw_buf_readb(dev, buf, offset+1); 1202 if (tmp 1203 != wd->ap.ssidLen[j]) 1204 { 1205 k++; 1206 } 1207 } 1208 if (k == wd->ap.vapNumber) 1209 { 1210 goto zlDeauth; 1211 } 1212 1213 k = 0; 1214 for (j = 0; j < wd->ap.vapNumber; j++) 1215 { 1216 for (i=0; i<wd->ap.ssidLen[j]; i++) 1217 { 1218 tmp = zmw_buf_readb(dev, buf, offset+2+i); 1219 if (tmp 1220 != wd->ap.ssid[j][i]) 1221 { 1222 break; 1223 } 1224 } 1225 if (i == wd->ap.ssidLen[j]) 1226 { 1227 apId = j; 1228 } 1229 else 1230 { 1231 k++; 1232 } 1233 } 1234 if (k == wd->ap.vapNumber) 1235 { 1236 goto zlDeauth; 1237 } 1238 } 1239 1240 /* TODO : check capability */ 1241 1242 /* AP : check support rate */ 1243 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE); 1244 if (offset != 0xffff) 1245 { 1246 /* 11g STA */ 1247 staType = 1; 1248 } 1249 //CWYang(+) 1250 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); 1251 if (offset != 0xffff) 1252 { 1253 /* 11n STA */ 1254 staType = 2; 1255 } 1256 1257 /* TODO : do not allow 11b STA to associated in Pure G mode */ 1258 if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_G && staType == 0) 1259 { 1260 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 3, 0, 0); 1261 return; 1262 } 1263 1264 /* In pure B mode, we set G STA into B mode */ 1265 if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_B && staType == 1) 1266 { 1267 staType = 0; 1268 } 1269 1270 /* AP : check 11i and WPA */ 1271 /* AP : check 11h */ 1272 1273 /* AP : check WME */ 1274 offset = zfFindWifiElement(dev, buf, 2, 0); 1275 if (offset != 0xffff) 1276 { 1277 /* WME STA */ 1278 qosType = 1; 1279 zm_msg0_mm(ZM_LV_0, "WME STA"); 1280 1281 if (wd->ap.uapsdEnabled != 0) 1282 { 1283 qosInfo = zmw_rx_buf_readb(dev, buf, offset+8); 1284 } 1285 } 1286 1287 if (wd->ap.wpaSupport[apId] == 1) 1288 { 1289 offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE); 1290 if (offset != 0xffff) 1291 { 1292 /* get WPA IE */ 1293 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); 1294 if (length+2 < ZM_MAX_WPAIE_SIZE) 1295 { 1296 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2); 1297 wd->ap.stawpaLen[apId] = length+2; 1298 encMode = 1; 1299 1300 1301 zm_msg1_mm(ZM_LV_0, "WPA Mode zfwAsocNotify, apId=", apId); 1302 1303 /* AP : Call zfwAsocNotify() */ 1304 if (wd->zfcbAsocNotify != NULL) 1305 { 1306 wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId); 1307 } 1308 } 1309 else 1310 { 1311 goto zlDeauth; 1312 } 1313 } 1314 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff ) 1315 { 1316 /* get RSN IE */ 1317 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); 1318 if (length+2 < ZM_MAX_WPAIE_SIZE) 1319 { 1320 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2); 1321 wd->ap.stawpaLen[apId] = length+2; 1322 encMode = 1; 1323 1324 zm_msg1_mm(ZM_LV_0, "RSN Mode zfwAsocNotify, apId=", apId); 1325 1326 /* AP : Call zfwAsocNotify() */ 1327 if (wd->zfcbAsocNotify != NULL) 1328 { 1329 wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId); 1330 } 1331 } 1332 else 1333 { 1334 goto zlDeauth; 1335 } 1336 } 1337#ifdef ZM_ENABLE_CENC 1338 else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff ) 1339 { 1340 /* get CENC IE */ 1341 u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); 1342 1343 if (length+2 < ZM_MAX_WPAIE_SIZE) 1344 { 1345 zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2); 1346 wd->ap.stawpaLen[apId] = length+2; 1347 encMode = 1; 1348 1349 zm_msg1_mm(ZM_LV_0, "CENC Mode zfwAsocNotify, apId=", apId); 1350 1351 /* AP : Call zfwAsocNotify() */ 1352 if (wd->zfcbCencAsocNotify != NULL) 1353 { 1354 wd->zfcbCencAsocNotify(dev, src, wd->ap.stawpaIe[apId], 1355 wd->ap.stawpaLen[apId], apId); 1356 } 1357 } 1358 else 1359 { 1360 goto zlDeauth; 1361 } 1362 } 1363#endif //ZM_ENABLE_CENC 1364 else 1365 { /* ap is encryption but sta has no wpa/rsn ie */ 1366 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0); 1367 return; 1368 } 1369 } 1370 /* sta has wpa/rsn ie but ap is no encryption */ 1371 if ((wd->ap.wpaSupport[apId] == 0) && (encMode == 1)) 1372 { 1373 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0); 1374 return; 1375 } 1376 1377 /* AP : update STA to asoc */ 1378 aid = zfApAddSta(dev, src, ZM_STATE_ASOC, apId, staType, qosType, qosInfo); 1379 1380 zfApStoreAsocReqIe(dev, buf, aid); 1381 1382zlDeauth: 1383 /* AP : send asoc rsp2 */ 1384 if (aid != 0xffff) 1385 { 1386 frameType = zmw_rx_buf_readb(dev, buf, 0); 1387 1388 if (frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ) 1389 { 1390 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCRSP, src, 0, aid+1, apId); 1391 } 1392 else 1393 { 1394 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCRSP, src, 0, aid+1, apId); 1395 } 1396 } 1397 else 1398 { 1399 /* TODO : send deauthentication */ 1400 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0); 1401 } 1402 1403 return; 1404} 1405 1406void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid) 1407{ 1408 //struct zsWlanAssoFrameHeader* pAssoFrame; 1409 //u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)]; 1410 u16_t offset; 1411 u32_t i; 1412 u16_t length; 1413 u8_t *htcap; 1414 1415 zmw_get_wlan_dev(dev); 1416 1417 for (i=0; i<wd->sta.asocRspFrameBodySize; i++) 1418 { 1419 wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24); 1420 } 1421 /* capability: 2 octets */ 1422 offset = 24; 1423 1424 /* Listen interval: 2 octets */ 1425 offset = 26; 1426 1427 /* SSID */ 1428 offset = 28; 1429 1430 /* supported rates */ 1431 offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE); 1432 if (offset == 0xffff) 1433 return; 1434 length = zmw_rx_buf_readb(dev, buf, offset + 1); 1435 1436 /* extended supported rates */ 1437 offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE); 1438 if (offset == 0xffff) 1439 return; 1440 length = zmw_rx_buf_readb(dev, buf, offset + 1); 1441 1442 /* power capability:4 octets */ 1443 offset = offset + 2 + length; 1444 1445 /* supported channels: 4 octets */ 1446 offset = offset + 2 + 4; 1447 1448 /* RSN */ 1449 1450 /* QoS */ 1451 1452 /* HT capabilities: 28 octets */ 1453 offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY); 1454 if (offset != 0xffff) { 1455 /* atheros pre n */ 1456 htcap = (u8_t *)&wd->ap.ie[aid].HtCap; 1457 htcap[0] = zmw_rx_buf_readb(dev, buf, offset); 1458 htcap[1] = 26; 1459 for (i=1; i<=26; i++) 1460 { 1461 htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i); 1462 zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i+1]); 1463 } 1464 return; 1465 } 1466 else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) { 1467 /* pre n 2.0 standard */ 1468 htcap = (u8_t *)&wd->ap.ie[aid].HtCap; 1469 for (i=0; i<28; i++) 1470 { 1471 htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i); 1472 zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i]); 1473 } 1474 } 1475 else { 1476 /* not 11n AP */ 1477 return; 1478 } 1479 1480 1481 /* supported regulatory classes */ 1482 offset = offset + length; 1483 //length = zmw_rx_buf_readb(dev, buf, offset + 1); 1484 { 1485 u8_t *htcap; 1486 htcap = (u8_t *)&wd->sta.ie.HtInfo; 1487 //zm_debug_msg2("ASOC: HT Capabilities info=", ((u16_t *)htcap)[1]); 1488 //zm_debug_msg2("ASOC: A-MPDU parameters=", htcap[4]); 1489 //zm_debug_msg2("ASOC: Supported MCS set=", ((u32_t *)htcap)[1]>>8); 1490 } 1491 1492} 1493 1494void zfApProcessAsocRsp(zdev_t* dev, zbuf_t* buf) 1495{ 1496 1497} 1498 1499void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) 1500{ 1501 u16_t aid; 1502 zmw_get_wlan_dev(dev); 1503 zmw_declare_for_critical_section(); 1504 1505 zmw_enter_critical_section(dev); 1506 /* AP : if SA=associated STA then deauthenticate STA */ 1507 aid = zfApFindSta(dev, src); 1508 if (aid != 0xffff) 1509 { 1510 /* Clear STA table */ 1511 wd->ap.staTable[aid].valid = 0; 1512 if (wd->zfcbDisAsocNotify != NULL) 1513 { 1514 wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId); 1515 } 1516 } 1517 zmw_leave_critical_section(dev); 1518 1519} 1520 1521void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) 1522{ 1523 u16_t aid; 1524 zmw_get_wlan_dev(dev); 1525 zmw_declare_for_critical_section(); 1526 1527 zmw_enter_critical_section(dev); 1528 /* AP : if SA=associated STA then deauthenticate STA */ 1529 aid = zfApFindSta(dev, src); 1530 if (aid != 0xffff) 1531 { 1532 /* Clear STA table */ 1533 wd->ap.staTable[aid].valid = 0; 1534 zmw_leave_critical_section(dev); 1535 if (wd->zfcbDisAsocNotify != NULL) 1536 { 1537 wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId); 1538 } 1539 } 1540 zmw_leave_critical_section(dev); 1541 1542} 1543 1544 1545void zfApProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) 1546{ 1547} 1548 1549/************************************************************************/ 1550/* */ 1551/* FUNCTION DESCRIPTION zfApAddIeSsid */ 1552/* Add AP information element SSID to buffer. */ 1553/* */ 1554/* INPUTS */ 1555/* dev : device pointer */ 1556/* buf : buffer to add information element */ 1557/* offset : add information element from this offset */ 1558/* vap : virtual AP ID */ 1559/* */ 1560/* OUTPUTS */ 1561/* buffer offset after adding information element */ 1562/* */ 1563/* AUTHOR */ 1564/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ 1565/* */ 1566/************************************************************************/ 1567u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) 1568{ 1569 u16_t i; 1570 1571 zmw_get_wlan_dev(dev); 1572 1573 /* Element ID */ 1574 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID); 1575 1576 /* Element Length */ 1577 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssidLen[vap]); 1578 1579 /* Information : SSID */ 1580 for (i=0; i<wd->ap.ssidLen[vap]; i++) 1581 { 1582 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssid[vap][i]); 1583 } 1584 1585 return offset; 1586} 1587 1588 1589/************************************************************************/ 1590/* */ 1591/* FUNCTION DESCRIPTION zfApAddIeTim */ 1592/* Add AP information element TIM to buffer. */ 1593/* */ 1594/* INPUTS */ 1595/* dev : device pointer */ 1596/* buf : buffer to add information element */ 1597/* offset : add information element from this offset */ 1598/* vap : virtual AP ID */ 1599/* */ 1600/* OUTPUTS */ 1601/* buffer offset after adding information element */ 1602/* */ 1603/* AUTHOR */ 1604/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ 1605/* */ 1606/************************************************************************/ 1607u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) 1608{ 1609 u8_t uniBitMap[9]; 1610 u16_t highestByte; 1611 u16_t i; 1612 u16_t lenOffset; 1613 u16_t id; 1614 u16_t dst[3]; 1615 u16_t aid; 1616 u16_t bitPosition; 1617 u16_t bytePosition; 1618 zbuf_t* psBuf; 1619 zbuf_t* tmpBufArray[ZM_UNI_ARRAY_SIZE]; 1620 u16_t tmpBufArraySize = 0; 1621 1622 zmw_get_wlan_dev(dev); 1623 1624 zmw_declare_for_critical_section(); 1625 1626 /* Element ID */ 1627 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_TIM); 1628 1629 /* offset of Element Length */ 1630 lenOffset = offset++; 1631 1632 /* Information : TIM */ 1633 /* DTIM count */ 1634 /* TODO : Doesn't work for Virtual AP's case */ 1635 wd->CurrentDtimCount++; 1636 if (wd->CurrentDtimCount >= wd->dtim) 1637 { 1638 wd->CurrentDtimCount = 0; 1639 } 1640 zmw_tx_buf_writeb(dev, buf, offset++, wd->CurrentDtimCount); 1641 /* DTIM period */ 1642 zmw_tx_buf_writeb(dev, buf, offset++, wd->dtim); 1643 /* bitmap offset */ 1644 zmw_tx_buf_writeb(dev, buf, offset++, 0); 1645 1646 /* Update BCMC bit */ 1647 if (wd->CurrentDtimCount == 0) 1648 { 1649 zmw_enter_critical_section(dev); 1650 wd->ap.timBcmcBit[vap] = (wd->ap.bcmcTail[vap]!=wd->ap.bcmcHead[vap])?1:0; 1651 zmw_leave_critical_section(dev); 1652 } 1653 else 1654 { 1655 wd->ap.timBcmcBit[vap] = 0; 1656 } 1657 1658 /* Update Unicast bitmap */ 1659 /* reset bit map */ 1660 for (i=0; i<9; i++) 1661 { 1662 uniBitMap[i] = 0; 1663 } 1664 highestByte = 0; 1665 1666 zmw_enter_critical_section(dev); 1667 1668 id = wd->ap.uniHead; 1669 while (id != wd->ap.uniTail) 1670 { 1671 psBuf = wd->ap.uniArray[id]; 1672 1673 /* TODO : Aging PS frame after queuing for more than 10 seconds */ 1674 1675 /* get destination STA's aid */ 1676 dst[0] = zmw_tx_buf_readh(dev, psBuf, 0); 1677 dst[1] = zmw_tx_buf_readh(dev, psBuf, 2); 1678 dst[2] = zmw_tx_buf_readh(dev, psBuf, 4); 1679 aid = zfApFindSta(dev, dst); 1680 if (aid != 0xffff) 1681 { 1682 if (wd->ap.staTable[aid].psMode != 0) 1683 { 1684 zm_msg1_mm(ZM_LV_0, "aid=",aid); 1685 aid++; 1686 zm_assert(aid<=64); 1687 bitPosition = (1 << (aid & 0x7)); 1688 bytePosition = (aid >> 3); 1689 uniBitMap[bytePosition] |= bitPosition; 1690 1691 if (bytePosition>highestByte) 1692 { 1693 highestByte = bytePosition; 1694 } 1695 id = (id+1) & (ZM_UNI_ARRAY_SIZE-1); 1696 } 1697 else 1698 { 1699 zm_msg0_mm(ZM_LV_0, "Send PS frame which STA no longer in PS mode"); 1700 /* Send PS frame which STA no longer in PS mode */ 1701 zfApRemoveFromPsQueue(dev, id, dst); 1702 tmpBufArray[tmpBufArraySize++] = psBuf; 1703 } 1704 } 1705 else 1706 { 1707 zm_msg0_mm(ZM_LV_0, "Free garbage PS frame"); 1708 /* Free garbage PS frame */ 1709 zfApRemoveFromPsQueue(dev, id, dst); 1710 zfwBufFree(dev, psBuf, 0); 1711 } 1712 } 1713 1714 zmw_leave_critical_section(dev); 1715 1716 zfQueueGenerateUapsdTim(dev, wd->ap.uapsdQ, uniBitMap, &highestByte); 1717 1718 zm_msg1_mm(ZM_LV_3, "bm=",uniBitMap[0]); 1719 zm_msg1_mm(ZM_LV_3, "highestByte=",highestByte); 1720 zm_msg1_mm(ZM_LV_3, "timBcmcBit[]=",wd->ap.timBcmcBit[vap]); 1721 1722 /* bitmap */ 1723 zmw_tx_buf_writeb(dev, buf, offset++, 1724 uniBitMap[0] | wd->ap.timBcmcBit[vap]); 1725 for (i=0; i<highestByte; i++) 1726 { 1727 zmw_tx_buf_writeb(dev, buf, offset++, uniBitMap[i+1]); 1728 } 1729 1730 /* Element Length */ 1731 zmw_tx_buf_writeb(dev, buf, lenOffset, highestByte+4); 1732 1733 for (i=0; i<tmpBufArraySize; i++) 1734 { 1735 /* Put to VTXQ[ac] */ 1736 zfPutVtxq(dev, tmpBufArray[i]); 1737 } 1738 /* Push VTXQ[ac] */ 1739 zfPushVtxq(dev); 1740 1741 return offset; 1742} 1743 1744 1745 1746/************************************************************************/ 1747/* */ 1748/* FUNCTION DESCRIPTION zfApRemoveFromPsQueue */ 1749/* Remove zbuf from PS queue. */ 1750/* */ 1751/* INPUTS */ 1752/* dev : device pointer */ 1753/* id : index in ps queue */ 1754/* */ 1755/* OUTPUTS */ 1756/* more data bit */ 1757/* */ 1758/* AUTHOR */ 1759/* Stephen Chen Atheros Communications, INC. 2007.1 */ 1760/* */ 1761/************************************************************************/ 1762u8_t zfApRemoveFromPsQueue(zdev_t* dev, u16_t id, u16_t* addr) 1763{ 1764 u16_t dst[3]; 1765 u16_t nid; 1766 u8_t moreData = 0; 1767 zmw_get_wlan_dev(dev); 1768 1769 wd->ap.uniTail = (wd->ap.uniTail-1) & (ZM_UNI_ARRAY_SIZE-1); 1770 while (id != wd->ap.uniTail) 1771 { 1772 nid = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1); 1773 wd->ap.uniArray[id] = wd->ap.uniArray[nid]; 1774 1775 /* Search until tail to config more data bit */ 1776 dst[0] = zmw_buf_readh(dev, wd->ap.uniArray[id], 0); 1777 dst[1] = zmw_buf_readh(dev, wd->ap.uniArray[id], 2); 1778 dst[2] = zmw_buf_readh(dev, wd->ap.uniArray[id], 4); 1779 if ((addr[0] == dst[0]) && (addr[1] == dst[1]) 1780 && (addr[2] == dst[2])) 1781 { 1782 moreData = 0x20; 1783 } 1784 1785 id = nid; 1786 } 1787 return moreData; 1788} 1789 1790/************************************************************************/ 1791/* */ 1792/* FUNCTION DESCRIPTION zfApAddIeWmePara */ 1793/* Add WME Parameter Element to buffer. */ 1794/* */ 1795/* INPUTS */ 1796/* dev : device pointer */ 1797/* buf : buffer to add information element */ 1798/* offset : add information element from this offset */ 1799/* vap : virtual AP ID */ 1800/* */ 1801/* OUTPUTS */ 1802/* buffer offset after adding information element */ 1803/* */ 1804/* AUTHOR */ 1805/* Stephen Chen ZyDAS Technology Corporation 2006.1 */ 1806/* */ 1807/************************************************************************/ 1808u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) 1809{ 1810 zmw_get_wlan_dev(dev); 1811 1812 /* Element ID */ 1813 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE); 1814 1815 /* Element Length */ 1816 zmw_tx_buf_writeb(dev, buf, offset++, 24); 1817 1818 /* OUI */ 1819 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1820 zmw_tx_buf_writeb(dev, buf, offset++, 0x50); 1821 zmw_tx_buf_writeb(dev, buf, offset++, 0xF2); 1822 zmw_tx_buf_writeb(dev, buf, offset++, 0x02); 1823 zmw_tx_buf_writeb(dev, buf, offset++, 0x01); 1824 zmw_tx_buf_writeb(dev, buf, offset++, 0x01); 1825 1826 /* QoS Info */ 1827 if (wd->ap.uapsdEnabled) 1828 { 1829 zmw_tx_buf_writeb(dev, buf, offset++, 0x81); 1830 } 1831 else 1832 { 1833 zmw_tx_buf_writeb(dev, buf, offset++, 0x01); 1834 } 1835 1836 /* Reserved */ 1837 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1838 1839 /* Best Effort AC parameters */ 1840 zmw_tx_buf_writeb(dev, buf, offset++, 0x03); 1841 zmw_tx_buf_writeb(dev, buf, offset++, 0xA4); 1842 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1843 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1844 /* Backfround AC parameters */ 1845 zmw_tx_buf_writeb(dev, buf, offset++, 0x27); 1846 zmw_tx_buf_writeb(dev, buf, offset++, 0xA4); 1847 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1848 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1849 /* Video AC parameters */ 1850 zmw_tx_buf_writeb(dev, buf, offset++, 0x42); 1851 zmw_tx_buf_writeb(dev, buf, offset++, 0x43); 1852 zmw_tx_buf_writeb(dev, buf, offset++, 0x5E); 1853 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1854 /* Voice AC parameters */ 1855 zmw_tx_buf_writeb(dev, buf, offset++, 0x62); 1856 zmw_tx_buf_writeb(dev, buf, offset++, 0x32); 1857 zmw_tx_buf_writeb(dev, buf, offset++, 0x2F); 1858 zmw_tx_buf_writeb(dev, buf, offset++, 0x00); 1859 1860 return offset; 1861} 1862 1863 1864/************************************************************************/ 1865/* */ 1866/* FUNCTION DESCRIPTION zfApSendBeacon */ 1867/* Sned AP mode beacon. */ 1868/* */ 1869/* INPUTS */ 1870/* dev : device pointer */ 1871/* */ 1872/* OUTPUTS */ 1873/* none */ 1874/* */ 1875/* AUTHOR */ 1876/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ 1877/* */ 1878/************************************************************************/ 1879void zfApSendBeacon(zdev_t* dev) 1880{ 1881 zbuf_t* buf; 1882 u16_t offset; 1883 u16_t vap; 1884 u16_t seq; 1885 1886 zmw_get_wlan_dev(dev); 1887 1888 zmw_declare_for_critical_section(); 1889 1890 wd->ap.beaconCounter++; 1891 if (wd->ap.beaconCounter >= wd->ap.vapNumber) 1892 { 1893 wd->ap.beaconCounter = 0; 1894 } 1895 vap = wd->ap.beaconCounter; 1896 1897 1898 zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap); 1899 1900 /* TBD : Maximum size of beacon */ 1901 buf = zfwBufAllocate(dev, 1024); 1902 if (buf == NULL) 1903 { 1904 zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!"); 1905 return; 1906 } 1907 1908 offset = 0; 1909 1910 /* wlan header */ 1911 /* Frame control */ 1912 zmw_tx_buf_writeh(dev, buf, offset, 0x0080); 1913 offset+=2; 1914 /* Duration */ 1915 zmw_tx_buf_writeh(dev, buf, offset, 0x0000); 1916 offset+=2; 1917 /* Address 1 */ 1918 zmw_tx_buf_writeh(dev, buf, offset, 0xffff); 1919 offset+=2; 1920 zmw_tx_buf_writeh(dev, buf, offset, 0xffff); 1921 offset+=2; 1922 zmw_tx_buf_writeh(dev, buf, offset, 0xffff); 1923 offset+=2; 1924 /* Address 2 */ 1925 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]); 1926 offset+=2; 1927 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]); 1928 offset+=2; 1929#ifdef ZM_VAPMODE_MULTILE_SSID 1930 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID 1931#else 1932 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP 1933#endif 1934 offset+=2; 1935 /* Address 3 */ 1936 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]); 1937 offset+=2; 1938 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]); 1939 offset+=2; 1940#ifdef ZM_VAPMODE_MULTILE_SSID 1941 zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID 1942#else 1943 zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP 1944#endif 1945 offset+=2; 1946 1947 /* Sequence number */ 1948 zmw_enter_critical_section(dev); 1949 seq = ((wd->mmseq++)<<4); 1950 zmw_leave_critical_section(dev); 1951 zmw_tx_buf_writeh(dev, buf, offset, seq); 1952 offset+=2; 1953 1954 /* 24-31 Time Stamp : hardware will fill this field */ 1955 zmw_tx_buf_writeh(dev, buf, offset, 0); 1956 zmw_tx_buf_writeh(dev, buf, offset+2, 0); 1957 zmw_tx_buf_writeh(dev, buf, offset+4, 0); 1958 zmw_tx_buf_writeh(dev, buf, offset+6, 0); 1959 offset+=8; 1960 1961 /* Beacon Interval */ 1962 zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval); 1963 offset+=2; 1964 1965 /* Capability */ 1966 zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]); 1967 offset+=2; 1968 1969 /* SSID */ 1970 if (wd->ap.hideSsid[vap] == 0) 1971 { 1972 offset = zfApAddIeSsid(dev, buf, offset, vap); 1973 } 1974 else 1975 { 1976 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID); 1977 zmw_tx_buf_writeb(dev, buf, offset++, 0); 1978 1979 } 1980 1981 /* Support Rate */ 1982 if ( wd->frequency < 3000 ) 1983 { 1984 offset = zfMmAddIeSupportRate(dev, buf, offset, 1985 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); 1986 } 1987 else 1988 { 1989 offset = zfMmAddIeSupportRate(dev, buf, offset, 1990 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); 1991 } 1992 1993 /* DS parameter set */ 1994 offset = zfMmAddIeDs(dev, buf, offset); 1995 1996 /* TIM */ 1997 offset = zfApAddIeTim(dev, buf, offset, vap); 1998 1999 /* If WLAN Type is not PURE B */ 2000 if (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B) 2001 { 2002 if ( wd->frequency < 3000 ) 2003 { 2004 /* ERP Information */ 2005 offset = zfMmAddIeErp(dev, buf, offset); 2006 2007 /* Extended Supported Rates */ 2008 offset = zfMmAddIeSupportRate(dev, buf, offset, 2009 ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); 2010 } 2011 } 2012 2013 /* TODO : country information */ 2014 /* TODO : RSN */ 2015 if (wd->ap.wpaSupport[vap] == 1) 2016 { 2017 offset = zfMmAddIeWpa(dev, buf, offset, vap); 2018 } 2019 2020 /* WME Parameters */ 2021 if (wd->ap.qosMode == 1) 2022 { 2023 offset = zfApAddIeWmePara(dev, buf, offset, vap); 2024 } 2025 2026 /* HT Capabilities Info */ 2027 offset = zfMmAddHTCapability(dev, buf, offset); 2028 2029 /* Extended HT Capabilities Info */ 2030 offset = zfMmAddExtendedHTCapability(dev, buf, offset); 2031 2032 /* 1212 : write to beacon fifo */ 2033 /* 1221 : write to share memory */ 2034 zfHpSendBeacon(dev, buf, offset); 2035 2036 /* Free beacon buffer */ 2037 /* TODO: In order to fit the madwifi beacon architecture, we need to 2038 free beacon buffer in the HAL layer. 2039 */ 2040 2041 //zfwBufFree(dev, buf, 0); 2042} 2043 2044 2045/************************************************************************/ 2046/* */ 2047/* FUNCTION DESCRIPTION zfIntrabssForward */ 2048/* Called to transmit intra-BSS frame from upper layer. */ 2049/* */ 2050/* INPUTS */ 2051/* dev : device pointer */ 2052/* buf : buffer pointer */ 2053/* vap : virtual AP */ 2054/* */ 2055/* OUTPUTS */ 2056/* 1 : unicast intras-BSS frame */ 2057/* 0 : other frames */ 2058/* */ 2059/* AUTHOR */ 2060/* Stephen ZyDAS Technology Corporation 2005.11 */ 2061/* */ 2062/************************************************************************/ 2063u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap) 2064{ 2065 u16_t err; 2066 u16_t asocFlag = 0; 2067 u16_t dst[3]; 2068 u16_t aid; 2069 u16_t staState; 2070 zbuf_t* txBuf; 2071 u16_t len; 2072 u16_t i; 2073 u16_t temp; 2074 u16_t ret; 2075 u8_t vap = 0; 2076#ifdef ZM_ENABLE_NATIVE_WIFI 2077 dst[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); 2078 dst[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); 2079 dst[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); 2080#else 2081 dst[0] = zmw_rx_buf_readh(dev, buf, 0); 2082 dst[1] = zmw_rx_buf_readh(dev, buf, 2); 2083 dst[2] = zmw_rx_buf_readh(dev, buf, 4); 2084#endif // ZM_ENABLE_NATIVE_WIFI 2085 2086 /* Do Intra-BSS forward(data copy) if necessary*/ 2087 if ((dst[0]&0x1) != 0x1) 2088 { 2089 aid = zfApGetSTAInfo(dev, dst, &staState, &vap); 2090 if ((aid != 0xffff) && (staState == ZM_STATE_ASOC) && (srcVap == vap)) 2091 { 2092 asocFlag = 1; 2093 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : asoc STA"); 2094 } 2095 2096 } 2097 else 2098 { 2099 vap = srcVap; 2100 zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : BCorMC"); 2101 } 2102 2103 /* destination address = associated STA or BC/MC */ 2104 if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1)) 2105 { 2106 /* Allocate frame */ 2107 txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE); 2108 if (txBuf == NULL) 2109 { 2110 zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!"); 2111 goto zlAllocError; 2112 } 2113 2114 /* Copy frame */ 2115 len = zfwBufGetSize(dev, buf); 2116 for (i=0; i<len; i+=2) 2117 { 2118 temp = zmw_rx_buf_readh(dev, buf, i); 2119 zmw_tx_buf_writeh(dev, txBuf, i, temp); 2120 } 2121 zfwBufSetSize(dev, txBuf, len); 2122 2123#ifdef ZM_ENABLE_NATIVE_WIFI 2124 /* Tx-A2 = Rx-A1, Tx-A3 = Rx-A2, Tx-A1 = Rx-A3 */ 2125 for (i=0; i<6; i+=2) 2126 { 2127 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+i); 2128 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A2_OFFSET+i, temp); 2129 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+i); 2130 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A3_OFFSET+i, temp); 2131 temp = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+i); 2132 zmw_tx_buf_writeh(dev, txBuf, ZM_WLAN_HEADER_A1_OFFSET+i, temp); 2133 } 2134 2135 #endif 2136 2137 /* Transmit frame */ 2138 /* Return error if port is disabled */ 2139 err = zfTxPortControl(dev, txBuf, vap); 2140 if (err == ZM_PORT_DISABLED) 2141 { 2142 err = ZM_ERR_TX_PORT_DISABLED; 2143 goto zlTxError; 2144 } 2145 2146 /* AP : Buffer frame for power saving STA */ 2147 ret = zfApBufferPsFrame(dev, txBuf, vap); 2148 if (ret == 0) 2149 { 2150 /* forward frame if not been buffered */ 2151 /* Put to VTXQ[ac] */ 2152 ret = zfPutVtxq(dev, txBuf); 2153 /* Push VTXQ[ac] */ 2154 zfPushVtxq(dev); 2155 2156 } 2157 } 2158 return asocFlag; 2159 2160zlTxError: 2161 zfwBufFree(dev, txBuf, 0); 2162zlAllocError: 2163 return asocFlag; 2164} 2165 2166struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf) 2167{ 2168 u8_t sa[6]; 2169 u16_t id = 0, macAddr[3]; 2170 2171 zmw_get_wlan_dev(dev); 2172 2173 zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A2_OFFSET, 6); 2174 2175 macAddr[0] = sa[0] + (sa[1] << 8); 2176 macAddr[1] = sa[2] + (sa[3] << 8); 2177 macAddr[2] = sa[4] + (sa[5] << 8); 2178 2179 id = zfApFindSta(dev, macAddr); 2180 if (id != 0xffff) 2181 return (&wd->ap.staTable[id].rxMicKey); 2182 2183 return NULL; 2184} 2185 2186struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType) 2187{ 2188 u8_t da[6]; 2189 u16_t id = 0, macAddr[3]; 2190 2191 zmw_get_wlan_dev(dev); 2192 2193 zfCopyFromIntTxBuffer(dev, buf, da, 0, 6); 2194 2195 macAddr[0] = da[0] + (da[1] << 8); 2196 macAddr[1] = da[2] + (da[3] << 8); 2197 macAddr[2] = da[4] + (da[5] << 8); 2198 2199 if ((macAddr[0] & 0x1)) 2200 { 2201 return (&wd->ap.bcMicKey[0]); 2202 } 2203 else if ((id = zfApFindSta(dev, macAddr)) != 0xffff) 2204 { 2205 *qosType = wd->ap.staTable[id].qosType; 2206 return (&wd->ap.staTable[id].txMicKey); 2207 } 2208 2209 return NULL; 2210} 2211 2212u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig) 2213{ 2214 u16_t staState; 2215 u16_t aid; 2216 u16_t psBit; 2217 u16_t src[3]; 2218 u16_t dst[1]; 2219 u16_t i; 2220 2221 zmw_get_wlan_dev(dev); 2222 2223 src[0] = zmw_rx_buf_readh(dev, buf, 10); 2224 src[1] = zmw_rx_buf_readh(dev, buf, 12); 2225 src[2] = zmw_rx_buf_readh(dev, buf, 14); 2226 2227 if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) 2228 { 2229 /* AP */ 2230 dst[0] = zmw_rx_buf_readh(dev, buf, 4); 2231 2232 psBit = (zmw_rx_buf_readb(dev, buf, 1) & 0x10) >> 4; 2233 /* Get AID and update STA PS mode */ 2234 aid = zfApGetSTAInfoAndUpdatePs(dev, src, &staState, vap, psBit, uapsdTrig); 2235 2236 /* if STA not associated, send deauth */ 2237 if ((aid == 0xffff) || (staState != ZM_STATE_ASOC)) 2238 { 2239 if ((dst[0]&0x1)==0) 2240 { 2241 zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 0x7, 2242 0, 0); 2243 } 2244 2245 return ZM_ERR_STA_NOT_ASSOCIATED; 2246 } 2247 } /* if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) */ 2248 else 2249 { 2250 /* WDS */ 2251 for (i=0; i<ZM_MAX_WDS_SUPPORT; i++) 2252 { 2253 if ((wd->ap.wds.wdsBitmap & (1<<i)) != 0) 2254 { 2255 if ((src[0] == wd->ap.wds.macAddr[i][0]) 2256 && (src[1] == wd->ap.wds.macAddr[i][1]) 2257 && (src[2] == wd->ap.wds.macAddr[i][2])) 2258 { 2259 *vap = 0x20 + i; 2260 break; 2261 } 2262 } 2263 } 2264 } 2265 return ZM_SUCCESS; 2266} 2267 2268void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf) 2269{ 2270 u16_t src[3]; 2271 u16_t dst[3]; 2272 zbuf_t* psBuf = NULL; 2273 u16_t id; 2274 u8_t moreData = 0; 2275 2276 zmw_get_wlan_dev(dev); 2277 2278 zmw_declare_for_critical_section(); 2279 2280 src[0] = zmw_tx_buf_readh(dev, buf, 10); 2281 src[1] = zmw_tx_buf_readh(dev, buf, 12); 2282 src[2] = zmw_tx_buf_readh(dev, buf, 14); 2283 2284 /* Find ps buffer for PsPoll */ 2285 zmw_enter_critical_section(dev); 2286 id = wd->ap.uniHead; 2287 while (id != wd->ap.uniTail) 2288 { 2289 psBuf = wd->ap.uniArray[id]; 2290 2291 dst[0] = zmw_tx_buf_readh(dev, psBuf, 0); 2292 dst[1] = zmw_tx_buf_readh(dev, psBuf, 2); 2293 dst[2] = zmw_tx_buf_readh(dev, psBuf, 4); 2294 2295 if ((src[0] == dst[0]) && (src[1] == dst[1]) && (src[2] == dst[2])) 2296 { 2297 moreData = zfApRemoveFromPsQueue(dev, id, src); 2298 break; 2299 } 2300 else 2301 { 2302 psBuf = NULL; 2303 } 2304 id = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1); 2305 } 2306 zmw_leave_critical_section(dev); 2307 2308 /* Send ps buffer */ 2309 if (psBuf != NULL) 2310 { 2311 /* Send with more data bit */ 2312 zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, moreData); 2313 } 2314 2315 return; 2316} 2317 2318void zfApSetProtectionMode(zdev_t* dev, u16_t mode) 2319{ 2320 zmw_get_wlan_dev(dev); 2321 2322 if (mode == 0) 2323 { 2324 if (wd->ap.protectionMode != mode) 2325 { 2326 /* Write MAC&PHY registers to disable protection */ 2327 2328 wd->ap.protectionMode = mode; 2329 } 2330 2331 } 2332 else 2333 { 2334 if (wd->ap.protectionMode != mode) 2335 { 2336 /* Write MAC&PHY registers to enable protection */ 2337 2338 wd->ap.protectionMode = mode; 2339 } 2340 } 2341 return; 2342} 2343 2344 2345/************************************************************************/ 2346/* */ 2347/* FUNCTION DESCRIPTION zfApSendFailure */ 2348/* Send failure. */ 2349/* */ 2350/* INPUTS */ 2351/* dev : device pointer */ 2352/* addr : receiver address */ 2353/* */ 2354/* OUTPUTS */ 2355/* None */ 2356/* */ 2357/* AUTHOR */ 2358/* Stephen Chen Atheros Communications, INC. 2007.1 */ 2359/* */ 2360/************************************************************************/ 2361void zfApSendFailure(zdev_t* dev, u8_t* addr) 2362{ 2363 u16_t id; 2364 u16_t staAddr[3]; 2365 zmw_get_wlan_dev(dev); 2366 zmw_declare_for_critical_section(); 2367 2368 staAddr[0] = addr[0] + (((u16_t)addr[1])<<8); 2369 staAddr[1] = addr[2] + (((u16_t)addr[3])<<8); 2370 staAddr[2] = addr[4] + (((u16_t)addr[5])<<8); 2371 zmw_enter_critical_section(dev); 2372 id = zfApFindSta(dev, staAddr); 2373 if (id != 0xffff) 2374 { 2375 /* Send failture : Add 3 minutes to inactive time that will */ 2376 /* will make STA been kicked out soon */ 2377 wd->ap.staTable[id].time -= (3*ZM_TICK_PER_MINUTE); 2378 } 2379 zmw_leave_critical_section(dev); 2380} 2381 2382 2383void zfApProcessAction(zdev_t* dev, zbuf_t* buf) 2384{ 2385 u8_t category; 2386 2387 //zmw_get_wlan_dev(dev); 2388 2389 //zmw_declare_for_critical_section(); 2390 2391 category = zmw_rx_buf_readb(dev, buf, 24); 2392 2393 switch (category) 2394 { 2395 case ZM_WLAN_BLOCK_ACK_ACTION_FRAME: 2396 zfAggBlockAckActionFrame(dev, buf); 2397 break; 2398 default: 2399 break; 2400 } 2401 2402 return; 2403} 2404