Merge branch 'for-linus' of git://www.jni.nu/cris
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / otus / 80211core / cmm.c
CommitLineData
4bd43f50
LR
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 management */
21/* frame. */
22/* */
23/* NOTES */
24/* None */
25/* */
26/************************************************************************/
27#include "cprecomp.h"
28#include "../hal/hpreg.h"
29
30/* TODO : put all constant tables to a file */
31const u8_t zg11bRateTbl[4] = {2, 4, 11, 22};
32const u8_t zg11gRateTbl[8] = {12, 18, 24, 36, 48, 72, 96, 108};
33
34/* 0xff => element does not exist */
35const u8_t zgElementOffsetTable[] =
36{
37 4, /* 0 : asoc req */
38 6, /* 1 : asoc rsp */
39 10, /* 2 : reasoc req*/
40 6, /* 3 : reasoc rsp */
41 0, /* 4 : probe req */
42 12, /* 5 : probe rsp */
43 0xff, /* 6 : reserved */
44 0xff, /* 7 : reserved */
45 12, /* 8 : beacon */
46 4, /* 9 : ATIM */
47 0xff, /* 10 : disasoc */
48 6, /* 11 : auth */
49 0xff, /* 12 : deauth */
50 4, /* 13 : action */
51 0xff, /* 14 : reserved */
52 0xff, /* 15 : reserved */
53};
54
55/************************************************************************/
56/* */
57/* FUNCTION DESCRIPTION zfFindElement */
58/* Find a specific element in management frame */
59/* */
60/* INPUTS */
61/* dev : device pointer */
62/* buf : management frame buffer */
63/* eid : target element id */
64/* */
65/* OUTPUTS */
66/* byte offset of target element */
67/* or 0xffff if not found */
68/* */
69/* AUTHOR */
70/* Stephen Chen ZyDAS Technology Corporation 2005.10 */
71/* */
72/************************************************************************/
73u16_t zfFindElement(zdev_t* dev, zbuf_t* buf, u8_t eid)
74{
75 u8_t subType;
76 u16_t offset;
77 u16_t bufLen;
78 u16_t elen;
79 u8_t id, HTEid=0;
80 u8_t oui[4] = {0x00, 0x50, 0xf2, 0x01};
81 u8_t oui11n[3] = {0x00,0x90,0x4C};
82 u8_t HTType = 0;
83
84 /* Get offset of first element */
85 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
92363b52
JP
86 offset = zgElementOffsetTable[subType];
87 if (offset == 0xff)
4bd43f50
LR
88 {
89 zm_assert(0);
90 }
91
92 /* Plus wlan header */
93 offset += 24;
94
95 // jhlee HT 0
96
97 if ((eid == ZM_WLAN_EID_HT_CAPABILITY) ||
98 (eid == ZM_WLAN_EID_EXTENDED_HT_CAPABILITY))
99 {
100 HTEid = eid;
101 eid = ZM_WLAN_EID_WPA_IE;
102 HTType = 1;
103 }
104
105
106 bufLen = zfwBufGetSize(dev, buf);
107 /* Search loop */
108 while ((offset+2)<bufLen) // including element ID and length (2bytes)
109 {
110 /* Search target element */
92363b52
JP
111 id = zmw_rx_buf_readb(dev, buf, offset);
112 if (id == eid)
4bd43f50
LR
113 {
114 /* Bingo */
92363b52
JP
115 elen = zmw_rx_buf_readb(dev, buf, offset+1);
116 if (elen > bufLen - offset)
4bd43f50
LR
117 {
118 /* Element length error */
119 return 0xffff;
120 }
121
122 if ( elen == 0 && eid != ZM_WLAN_EID_SSID)
123 {
124 /* Element length error */
125 return 0xffff;
126 }
127
128 if ( eid == ZM_WLAN_EID_WPA_IE )
129 {
130 /* avoid sta to be thought use 11n when find a WPA_IE */
131 if ( (HTType == 0) && zfRxBufferEqualToStr(dev, buf, oui, offset+2, 4) )
132 {
133 return offset;
134 }
135
136 // jhlee HT 0
137 // CWYang(+)
138
139 if ((HTType == 1) && ( zfRxBufferEqualToStr(dev, buf, oui11n, offset+2, 3) ))
140 {
141 if ( zmw_rx_buf_readb(dev, buf, offset+5) == HTEid )
142 {
143 return offset + 5;
144 }
145 }
146
147 }
148 else
149 {
150 return offset;
151 }
152 }
153 /* Advance to next element */
154 #if 1
155 elen = zmw_rx_buf_readb(dev, buf, offset+1);
156 #else
92363b52
JP
157 elen = zmw_rx_buf_readb(dev, buf, offset+1);
158 if (elen == 0)
4bd43f50
LR
159 {
160 return 0xffff;
161 }
162 #endif
163
164 offset += (elen+2);
165 }
166 return 0xffff;
167}
168
169
170/************************************************************************/
171/* */
172/* FUNCTION DESCRIPTION zfFindWifiElement */
173/* Find a specific Wifi element in management frame */
174/* */
175/* INPUTS */
176/* dev : device pointer */
177/* buf : management frame buffer */
178/* type : OUI type */
179/* subType : OUI subtype */
180/* */
181/* OUTPUTS */
182/* byte offset of target element */
183/* or 0xffff if not found */
184/* */
185/* AUTHOR */
186/* Stephen Chen ZyDAS Technology Corporation 2006.1 */
187/* */
188/************************************************************************/
189u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype)
190{
191 u8_t subType;
192 u16_t offset;
193 u16_t bufLen;
194 u16_t elen;
195 u8_t id;
196 u8_t tmp;
197
198 /* Get offset of first element */
199 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
200
92363b52
JP
201 offset = zgElementOffsetTable[subType];
202 if (offset == 0xff)
4bd43f50
LR
203 {
204 zm_assert(0);
205 }
206
207 /* Plus wlan header */
208 offset += 24;
209
210 bufLen = zfwBufGetSize(dev, buf);
211 /* Search loop */
212 while ((offset+2)<bufLen) // including element ID and length (2bytes)
213 {
214 /* Search target element */
92363b52
JP
215 id = zmw_rx_buf_readb(dev, buf, offset);
216 if (id == ZM_WLAN_EID_WIFI_IE)
4bd43f50
LR
217 {
218 /* Bingo */
92363b52
JP
219 elen = zmw_rx_buf_readb(dev, buf, offset+1);
220 if (elen > bufLen - offset)
4bd43f50
LR
221 {
222 /* Element length error */
223 return 0xffff;
224 }
225
226 if ( elen == 0 )
227 {
228 return 0xffff;
229 }
230
231 if (((tmp = zmw_rx_buf_readb(dev, buf, offset+2)) == 0x00)
232 && ((tmp = zmw_rx_buf_readb(dev, buf, offset+3)) == 0x50)
233 && ((tmp = zmw_rx_buf_readb(dev, buf, offset+4)) == 0xF2)
234 && ((tmp = zmw_rx_buf_readb(dev, buf, offset+5)) == type))
235
236 {
237 if ( subtype != 0xff )
238 {
92363b52
JP
239 tmp = zmw_rx_buf_readb(dev, buf, offset+6);
240 if (tmp == subtype)
4bd43f50
LR
241 {
242 return offset;
243 }
244 }
245 else
246 {
247 return offset;
248 }
249 }
250 }
251 /* Advance to next element */
92363b52
JP
252 elen = zmw_rx_buf_readb(dev, buf, offset+1);
253 if (elen == 0)
4bd43f50
LR
254 {
255 return 0xffff;
256 }
257 offset += (elen+2);
258 }
259 return 0xffff;
260}
261
262u16_t zfRemoveElement(zdev_t* dev, u8_t* buf, u16_t size, u8_t eid)
263{
264 u16_t offset = 0;
265 u16_t elen;
266 u8_t HTEid = 0;
267 u8_t oui[4] = {0x00, 0x50, 0xf2, 0x01};
268 u8_t oui11n[3] = {0x00,0x90,0x4C};
269 u8_t HTType = 0;
270
271 if ((eid == ZM_WLAN_EID_HT_CAPABILITY) ||
272 (eid == ZM_WLAN_EID_EXTENDED_HT_CAPABILITY))
273 {
274 HTEid = eid;
275 eid = ZM_WLAN_EID_WPA_IE;
276 HTType = 1;
277 }
278
279 while (offset < size)
280 {
281 elen = *(buf+offset+1);
282
283 if (*(buf+offset) == eid)
284 {
285 if ( eid == ZM_WLAN_EID_WPA_IE )
286 {
287 if ( (HTType == 0)
288 && (*(buf+offset+2) == oui[0])
289 && (*(buf+offset+3) == oui[1])
290 && (*(buf+offset+4) == oui[2])
291 && (*(buf+offset+5) == oui[3]) )
292 {
293 zfMemoryMove(buf+offset, buf+offset+elen+2, size-offset-elen-2);
294 return (size-elen-2);
295 }
296
297 if ( (HTType == 1)
298 && (*(buf+offset+2) == oui11n[0])
299 && (*(buf+offset+3) == oui11n[1])
300 && (*(buf+offset+4) == oui11n[2])
301 && (*(buf+offset+5) == HTEid) )
302 {
303 zfMemoryMove(buf+offset, buf+offset+elen+2, size-offset-elen-2);
304 return (size-elen-2);
305 }
306 }
307 else
308 {
309 zfMemoryMove(buf+offset, buf+offset+elen+2, size-offset-elen-2);
310 return (size-elen-2);
311 }
312 }
313
314 offset += (elen+2);
315 }
316
317 return size;
318}
319
320u16_t zfUpdateElement(zdev_t* dev, u8_t* buf, u16_t size, u8_t* updateeid)
321{
322 u16_t offset = 0;
323 u16_t elen;
324
325 while (offset < size) {
326 elen = *(buf+offset+1);
327
328 if (*(buf+offset) == updateeid[0]) {
329 if (updateeid[1] <= elen) {
330 zfMemoryMove(buf+offset, updateeid, updateeid[1]+2);
331 zfMemoryMove(buf+offset+updateeid[1]+2, buf+offset+elen+2, size-offset-elen-2);
332
333 return size-(elen-updateeid[1]);
334 } else {
335 zfMemoryMove(buf+offset+updateeid[1]+2, buf+offset+elen+2, size-offset-elen-2);
336 zfMemoryMove(buf+offset, updateeid, updateeid[1]+2);
337
338 return size+(updateeid[1]-elen);
339 }
340 }
341
342 offset += (elen+2);
343 }
344
345 return size;
346}
347
348u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type)
349{
350 u8_t subType;
351 u16_t offset;
352 u16_t bufLen;
353 u16_t elen;
354 u8_t id;
355 u8_t super_feature;
356 u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00};
357
4bd43f50
LR
358 /* Get offset of first element */
359 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
92363b52
JP
360 offset = zgElementOffsetTable[subType];
361 if (offset == 0xff)
4bd43f50
LR
362 {
363 zm_assert(0);
364 }
365
366 /* Plus wlan header */
367 offset += 24;
368
369 bufLen = zfwBufGetSize(dev, buf);
370 /* Search loop */
371 while ((offset+2)<bufLen) // including element ID and length (2bytes)
372 {
373 /* Search target element */
92363b52
JP
374 id = zmw_rx_buf_readb(dev, buf, offset);
375 if (id == ZM_WLAN_EID_VENDOR_PRIVATE)
4bd43f50
LR
376 {
377 /* Bingo */
92363b52
JP
378 elen = zmw_rx_buf_readb(dev, buf, offset+1);
379 if (elen > bufLen - offset)
4bd43f50
LR
380 {
381 /* Element length error */
382 return 0xffff;
383 }
384
385 if ( elen == 0 )
386 {
387 return 0xffff;
388 }
389
390 if (zfRxBufferEqualToStr(dev, buf, ouiSuperG, offset+2, 6) && ( zmw_rx_buf_readb(dev, buf, offset+1) >= 6))
391 {
392 /* super_feature 0:useFastFrame, 1:useCompression, 2:useTurboPrime */
393 super_feature= zmw_rx_buf_readb(dev, buf, offset+8);
394 if ((super_feature & 0x01) || (super_feature & 0x02) || (super_feature & 0x04))
395 {
396 return offset;
397 }
398 }
399 }
400 /* Advance to next element */
401 #if 1
402 elen = zmw_rx_buf_readb(dev, buf, offset+1);
403 #else
92363b52
JP
404 elen = zmw_rx_buf_readb(dev, buf, offset+1);
405 if (elen == 0)
4bd43f50
LR
406 {
407 return 0xffff;
408 }
409 #endif
410
411 offset += (elen+2);
412 }
413 return 0xffff;
414}
415
416u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type)
417{
418 u8_t subType;
419 u16_t offset;
420 u16_t bufLen;
421 u16_t elen;
422 u8_t id;
423 u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00};
424
4bd43f50
LR
425 /* Get offset of first element */
426 subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4);
92363b52
JP
427 offset = zgElementOffsetTable[subType];
428 if (offset == 0xff)
4bd43f50
LR
429 {
430 zm_assert(0);
431 }
432
433 /* Plus wlan header */
434 offset += 24;
435
436 bufLen = zfwBufGetSize(dev, buf);
437 /* Search loop */
438 while ((offset+2)<bufLen) // including element ID and length (2bytes)
439 {
440 /* Search target element */
92363b52
JP
441 id = zmw_rx_buf_readb(dev, buf, offset);
442 if (id == ZM_WLAN_EID_VENDOR_PRIVATE)
4bd43f50
LR
443 {
444 /* Bingo */
92363b52
JP
445 elen = zmw_rx_buf_readb(dev, buf, offset+1);
446 if (elen > bufLen - offset)
4bd43f50
LR
447 {
448 /* Element length error */
449 return 0xffff;
450 }
451
452 if ( elen == 0 )
453 {
454 return 0xffff;
455 }
456
457 if (zfRxBufferEqualToStr(dev, buf, ouixr, offset+2, 6) && ( zmw_rx_buf_readb(dev, buf, offset+1) >= 6))
458 {
459 return offset;
460 }
461 }
462 /* Advance to next element */
463 #if 1
464 elen = zmw_rx_buf_readb(dev, buf, offset+1);
465 #else
92363b52
JP
466 elen = zmw_rx_buf_readb(dev, buf, offset+1);
467 if (elen == 0)
4bd43f50
LR
468 {
469 return 0xffff;
470 }
471 #endif
472
473 offset += (elen+2);
474 }
475 return 0xffff;
476}
477
478/************************************************************************/
479/* */
480/* FUNCTION DESCRIPTION zfMmAddIeSupportRate */
481/* Add information element Support Rate to buffer. */
482/* */
483/* INPUTS */
484/* dev : device pointer */
485/* buf : buffer to add information element */
486/* offset : add information element from this offset */
487/* eid : element ID */
488/* rateSet : CCK or OFDM */
489/* */
490/* OUTPUTS */
491/* buffer offset after adding information element */
492/* */
493/* AUTHOR */
494/* Stephen Chen ZyDAS Technology Corporation 2005.10 */
495/* */
496/************************************************************************/
497u16_t zfMmAddIeSupportRate(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t eid, u8_t rateSet)
498{
499 u8_t len = 0;
500 u16_t i;
501
502 zmw_get_wlan_dev(dev);
503
504 //if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) )
505 //{
506 // return offset;
507 //}
508
509 /* Information : Support Rate */
510 if ( rateSet == ZM_RATE_SET_CCK )
511 {
512 for (i=0; i<4; i++)
513 {
514 if ((wd->bRate & (0x1<<i)) == (0x1<<i))
515 //if ((0xf & (0x1<<i)) == (0x1<<i))
516 {
517 zmw_tx_buf_writeb(dev, buf, offset+len+2,
518 zg11bRateTbl[i]+((wd->bRateBasic & (0x1<<i))<<(7-i)));
519 len++;
520 }
521 }
522 }
523 else if ( rateSet == ZM_RATE_SET_OFDM )
524 {
525 for (i=0; i<8; i++)
526 {
527 if ((wd->gRate & (0x1<<i)) == (0x1<<i))
528 //if ((0xff & (0x1<<i)) == (0x1<<i))
529 {
530 zmw_tx_buf_writeb(dev, buf, offset+len+2,
531 zg11gRateTbl[i]+((wd->gRateBasic & (0x1<<i))<<(7-i)));
532 len++;
533 }
534 }
535 }
536
537 if (len > 0)
538 {
539 /* Element ID */
540 zmw_tx_buf_writeb(dev, buf, offset, eid);
541
542 /* Element Length */
543 zmw_tx_buf_writeb(dev, buf, offset+1, len);
544
545 /* Return value */
546 offset += (2+len);
547 }
548
549 return offset;
550}
551
552/************************************************************************/
553/* */
554/* FUNCTION DESCRIPTION zfMmAddIeDs */
555/* Add information element DS to buffer. */
556/* */
557/* INPUTS */
558/* dev : device pointer */
559/* buf : buffer to add information element */
560/* offset : add information element from this offset */
561/* */
562/* OUTPUTS */
563/* buffer offset after adding information element */
564/* */
565/* AUTHOR */
566/* Stephen Chen ZyDAS Technology Corporation 2005.10 */
567/* */
568/************************************************************************/
569u16_t zfMmAddIeDs(zdev_t* dev, zbuf_t* buf, u16_t offset)
570{
571 zmw_get_wlan_dev(dev);
572
573 /* Element ID */
574 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_DS);
575
576 /* Element Length */
577 zmw_tx_buf_writeb(dev, buf, offset++, 1);
578
579 /* Information : DS */
580 zmw_tx_buf_writeb(dev, buf, offset++,
581 zfChFreqToNum(wd->frequency, NULL));
582
583 return offset;
584}
585
586
587/************************************************************************/
588/* */
589/* FUNCTION DESCRIPTION zfMmAddIeErp */
590/* Add information element ERP to buffer. */
591/* */
592/* INPUTS */
593/* dev : device pointer */
594/* buf : buffer to add information element */
595/* offset : add information element from this offset */
596/* */
597/* OUTPUTS */
598/* buffer offset after adding information element */
599/* */
600/* AUTHOR */
601/* Stephen Chen ZyDAS Technology Corporation 2005.10 */
602/* */
603/************************************************************************/
604u16_t zfMmAddIeErp(zdev_t* dev, zbuf_t* buf, u16_t offset)
605{
606 zmw_get_wlan_dev(dev);
607
608 /* Element ID */
609 zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_ERP);
610
611 /* Element Length */
612 zmw_tx_buf_writeb(dev, buf, offset++, 1);
613
614 /* Information : ERP */
615 zmw_tx_buf_writeb(dev, buf, offset++, wd->erpElement);
616
617 return offset;
618}
619
620
621/************************************************************************/
622/* */
623/* FUNCTION DESCRIPTION zfMmAddIeWpa */
624/* Add information element WPA to buffer. */
625/* */
626/* INPUTS */
627/* dev : device pointer */
628/* buf : buffer to add information element */
629/* offset : add information element from this offset */
630/* */
631/* OUTPUTS */
632/* buffer offset after adding information element */
633/* */
634/* AUTHOR */
635/* Yuan-Gu Wei ZyDAS Technology Corporation 2006.2 */
636/* */
637/************************************************************************/
638u16_t zfMmAddIeWpa(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t apId)
639{
640 //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
641 int i;
642
643 zmw_get_wlan_dev(dev);
644
645 /* Element ID */
646 //zmw_inttx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WPA_IE);
647
648 /* Element Length */
649 //zmw_inttx_buf_writeb(dev, buf, offset++, wd->ap.wpaLen);
650 for(i = 0; i < wd->ap.wpaLen[apId]; i++)
651 {
652 /* Information : WPA */
653 zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.wpaIe[apId][i]);
654 }
655
656 return offset;
657}
658
659/************************************************************************/
660/* */
661/* FUNCTION DESCRIPTION zfMmAddHTCapability */
662/* Add HT Capability Infomation to buffer. */
663/* */
664/* INPUTS */
665/* dev : device pointer */
666/* buf : buffer to add information element */
667/* offset : add information element from this offset */
668/* */
669/* OUTPUTS */
670/* buffer offset after adding information element */
671/* */
672/* AUTHOR */
673/* Chao-Wen Yang ZyDAS Technology Corporation 2006.06 */
674/* */
675/************************************************************************/
676u16_t zfMmAddHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset)
677{
678 u8_t OUI[3] = {0x0,0x90,0x4C};
679 u16_t i;
680
681 zmw_get_wlan_dev(dev);
682
683 /* Prob ID */
684 zmw_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WPA_IE);
685
686 if ( wd->wlanMode == ZM_MODE_AP )
687 {
688 /* Element Length */
689 zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Data.Length + 4);
690
691 /* OUI Data */
692 for (i = 0; i < 3; i++)
693 {
694 zmw_buf_writeb(dev, buf, offset++, OUI[i]);
695 }
696
697 /* Element Type ID */
698 zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Data.ElementID);
699
700 /* HT Capability Data */
701 for (i = 0; i < 26; i++)
702 {
703 zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Byte[i+2]);
704 }
705 }
706 else
707 {
708 /* Element Length */
709 zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Data.Length + 4);
710
711 /* OUI Data */
712 for (i = 0; i < 3; i++)
713 {
714 zmw_buf_writeb(dev, buf, offset++, OUI[i]);
715 }
716
717 /* Element Type ID */
718 zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Data.ElementID);
719
720 /* HT Capability Data */
721 for (i = 0; i < 26; i++)
722 {
723 zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Byte[i+2]);
724 }
725 }
726
727 return offset;
728}
729
730
731u16_t zfMmAddPreNHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset)
732{
733 //u8_t OUI[3] = {0x0,0x90,0x4C};
734 u16_t i;
735
736 zmw_get_wlan_dev(dev);
737
738 /* Prob ID */
739 zmw_buf_writeb(dev, buf, offset++, ZM_WLAN_PREN2_EID_HTCAPABILITY);
740
741 if ( wd->wlanMode == ZM_MODE_AP )
742 {
743 /* Element Length */
744 zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Data.Length);
745
746 /* HT Capability Data */
747 for (i = 0; i < 26; i++)
748 {
749 zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Byte[i+2]);
750 }
751 }
752 else
753 {
754 /* Element Length */
755 zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Data.Length);
756
757 /* HT Capability Data */
758 for (i = 0; i < 26; i++)
759 {
760 zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Byte[i+2]);
761 }
762 }
763
764 return offset;
765}
766
767/************************************************************************/
768/* */
769/* FUNCTION DESCRIPTION zfMmAddExtendedHTCapability */
770/* Add Extended HT Capability Infomation to buffer. */
771/* */
772/* INPUTS */
773/* dev : device pointer */
774/* buf : buffer to add information element */
775/* offset : add information element from this offset */
776/* */
777/* OUTPUTS */
778/* buffer offset after adding information element */
779/* */
780/* AUTHOR */
781/* Chao-Wen Yang ZyDAS Technology Corporation 2006.06 */
782/* */
783/************************************************************************/
784u16_t zfMmAddExtendedHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset)
785{
786 u8_t OUI[3] = {0x0,0x90,0x4C};
787 u16_t i;
788
789 zmw_get_wlan_dev(dev);
790
791 /* Prob ID */
792 zmw_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WPA_IE);
793
794 if ( wd->wlanMode == ZM_MODE_AP )
795 {
796 /* Element Length */
797 zmw_buf_writeb(dev, buf, offset++, wd->ap.ExtHTCap.Data.Length + 4);
798
799 /* OUI Data */
800 for (i = 0; i < 3; i++)
801 {
802 zmw_buf_writeb(dev, buf, offset++, OUI[i]);
803 }
804
805 /* Element Type ID */
806 zmw_buf_writeb(dev, buf, offset++, wd->ap.ExtHTCap.Data.ElementID);
807
808 /* HT Capability Data */
809 for (i = 0; i < 22; i++)
810 {
811 zmw_buf_writeb(dev, buf, offset++, wd->ap.ExtHTCap.Byte[i+2]);
812 }
813 }
814 else
815 {
816 /* Element Length */
817 zmw_buf_writeb(dev, buf, offset++, wd->sta.ExtHTCap.Data.Length + 4);
818
819 /* OUI Data */
820 for (i = 0; i < 3; i++)
821 {
822 zmw_buf_writeb(dev, buf, offset++, OUI[i]);
823 }
824
825 /* Element Type ID */
826 zmw_buf_writeb(dev, buf, offset++, wd->sta.ExtHTCap.Data.ElementID);
827
828 /* HT Capability Data */
829 for (i = 0; i < 22; i++)
830 {
831 zmw_buf_writeb(dev, buf, offset++, wd->sta.ExtHTCap.Byte[i+2]);
832 }
833 }
834
835 return offset;
836}
837
838
839
840/************************************************************************/
841/* */
842/* FUNCTION DESCRIPTION zfSendMmFrame */
843/* Send management frame. */
844/* */
845/* INPUTS */
846/* dev : device pointer */
847/* frameType : management frame type */
848/* dst : destination MAC address */
849/* p1 : parameter 1 */
850/* p2 : parameter 2 */
851/* p3 : parameter 3 */
852/* */
853/* OUTPUTS */
854/* none */
855/* */
856/* AUTHOR */
857/* Stephen Chen ZyDAS Technology Corporation 2005.10 */
858/* */
859/************************************************************************/
860/* probe req : p1=> bWithSSID, p2=>R, p3=>R */
861/* probe rsp : p1=>R, p2=>R, p3=>VAP ID(AP) */
862/* deauth : p1=>Reason Code, p2=>R, p3=>VAP ID(AP) */
863/* Disasoc : p1=>Reason Code, p2=>R, p3=>VAP ID(AP) */
864/* ATIM : p1=>R, p2=>R, p3=>R */
865/* (re)asoc rsp : p1=>Status Code, p2=>AID, p3=>VAP ID(AP) */
866/* asoc req : p1=>R, p2=>R, p3=>R */
867/* reasoc req : p1=>AP MAC[0], p2=>AP MAC[1], p3=>AP MAC[2] */
868/* auth : p1=>low=Algorithm, high=Transaction, p2=>Status, p3=>VAP ID */
869void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst,
870 u32_t p1, u32_t p2, u32_t p3)
871{
872 zbuf_t* buf;
873 //u16_t addrTblSize;
874 //struct zsAddrTbl addrTbl;
875 u16_t offset = 0;
876 u16_t hlen = 32;
877 u16_t header[(24+25+1)/2];
878 u16_t vap = 0;
879 u16_t i;
880 u8_t encrypt = 0;
881 u16_t aid;
882
883 zmw_get_wlan_dev(dev);
884 zmw_declare_for_critical_section();
885
886 zm_msg2_mm(ZM_LV_2, "Send mm frame, type=", frameType);
658ce9d6 887 /* TBD : Maximum size of management frame */
92363b52
JP
888 buf = zfwBufAllocate(dev, 1024);
889 if (buf == NULL)
4bd43f50
LR
890 {
891 zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!");
892 return;
893 }
894
895 //Reserve room for wlan header
896 offset = hlen;
897
898 switch (frameType)
899 {
900 case ZM_WLAN_FRAME_TYPE_PROBEREQ :
901 offset = zfSendProbeReq(dev, buf, offset, (u8_t) p1);
902 break;
903
904 case ZM_WLAN_FRAME_TYPE_PROBERSP :
905 zm_msg0_mm(ZM_LV_3, "probe rsp");
906 /* 24-31 Time Stamp : hardware WON'T fill this field */
907 zmw_tx_buf_writeh(dev, buf, offset, 0);
908 zmw_tx_buf_writeh(dev, buf, offset+2, 0);
909 zmw_tx_buf_writeh(dev, buf, offset+4, 0);
910 zmw_tx_buf_writeh(dev, buf, offset+6, 0);
911 offset+=8;
912
913 /* Beacon Interval */
914 zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval);
915 offset+=2;
916
917 if (wd->wlanMode == ZM_MODE_AP)
918 {
919 vap = (u16_t) p3;
920 /* Capability */
921 zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]);
922 offset+=2;
923 /* SSID */
924 offset = zfApAddIeSsid(dev, buf, offset, vap);
925 }
926 else
927 {
928 /* Capability */
929 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]);
930 zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]);
931 /* SSID */
932 offset = zfStaAddIeSsid(dev, buf, offset);
933 }
934
935 /* Support Rate */
936 if ( wd->frequency < 3000 )
937 {
938 offset = zfMmAddIeSupportRate(dev, buf, offset,
939 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK);
940 }
941 else
942 {
943 offset = zfMmAddIeSupportRate(dev, buf, offset,
944 ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM);
945 }
946
947 /* DS parameter set */
948 offset = zfMmAddIeDs(dev, buf, offset);
949
950