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