]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/vt6655/wmgr.c
Merge tag 'iio-for-3.10a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23...
[karo-tx-linux.git] / drivers / staging / vt6655 / wmgr.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  *
20  * File: wmgr.c
21  *
22  * Purpose: Handles the 802.11 management functions
23  *
24  * Author: Lyndon Chen
25  *
26  * Date: May 8, 2002
27  *
28  * Functions:
29  *      nsMgrObjectInitial - Initialize Management Object data structure
30  *      vMgrObjectReset - Reset Management Object data structure
31  *      vMgrAssocBeginSta - Start associate function
32  *      vMgrReAssocBeginSta - Start reassociate function
33  *      vMgrDisassocBeginSta - Start disassociate function
34  *      s_vMgrRxAssocRequest - Handle Rcv associate_request
35  *      s_vMgrRxAssocResponse - Handle Rcv associate_response
36  *      vMrgAuthenBeginSta - Start authentication function
37  *      vMgrDeAuthenDeginSta - Start deauthentication function
38  *      s_vMgrRxAuthentication - Handle Rcv authentication
39  *      s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1
40  *      s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2
41  *      s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3
42  *      s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4
43  *      s_vMgrRxDisassociation - Handle Rcv disassociation
44  *      s_vMgrRxBeacon - Handle Rcv Beacon
45  *      vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS
46  *      vMgrJoinBSSBegin - Join BSS function
47  *      s_vMgrSynchBSS - Synch & adopt BSS parameters
48  *      s_MgrMakeBeacon - Create Baecon frame
49  *      s_MgrMakeProbeResponse - Create Probe Response frame
50  *      s_MgrMakeAssocRequest - Create Associate Request frame
51  *      s_MgrMakeReAssocRequest - Create ReAssociate Request frame
52  *      s_vMgrRxProbeResponse - Handle Rcv probe_response
53  *      s_vMrgRxProbeRequest - Handle Rcv probe_request
54  *      bMgrPrepareBeaconToSend - Prepare Beacon frame
55  *      s_vMgrLogStatus - Log 802.11 Status
56  *      vMgrRxManagePacket - Rcv management frame dispatch function
57  *      s_vMgrFormatTIM- Assembler TIM field of beacon
58  *      vMgrTimerInit- Initial 1-sec and command call back funtions
59  *
60  * Revision History:
61  *
62  */
63
64 #include "tmacro.h"
65 #include "desc.h"
66 #include "device.h"
67 #include "card.h"
68 #include "channel.h"
69 #include "80211hdr.h"
70 #include "80211mgr.h"
71 #include "wmgr.h"
72 #include "wcmd.h"
73 #include "mac.h"
74 #include "bssdb.h"
75 #include "power.h"
76 #include "datarate.h"
77 #include "baseband.h"
78 #include "rxtx.h"
79 #include "wpa.h"
80 #include "rf.h"
81 #include "iowpa.h"
82
83 #define PLICE_DEBUG
84
85 /*---------------------  Static Definitions -------------------------*/
86
87
88
89 /*---------------------  Static Classes  ----------------------------*/
90
91 /*---------------------  Static Variables  --------------------------*/
92 static int msglevel = MSG_LEVEL_INFO;
93 //static int          msglevel                =MSG_LEVEL_DEBUG;
94
95 /*---------------------  Static Functions  --------------------------*/
96 //2008-8-4 <add> by chester
97 static bool ChannelExceedZoneType(
98         PSDevice pDevice,
99         unsigned char byCurrChannel
100 );
101
102 // Association/diassociation functions
103 static
104 PSTxMgmtPacket
105 s_MgrMakeAssocRequest(
106         PSDevice pDevice,
107         PSMgmtObject pMgmt,
108         unsigned char *pDAddr,
109         unsigned short wCurrCapInfo,
110         unsigned short wListenInterval,
111         PWLAN_IE_SSID pCurrSSID,
112         PWLAN_IE_SUPP_RATES pCurrRates,
113         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
114 );
115
116 static
117 void
118 s_vMgrRxAssocRequest(
119         PSDevice pDevice,
120         PSMgmtObject pMgmt,
121         PSRxMgmtPacket pRxPacket,
122         unsigned int uNodeIndex
123 );
124
125 static
126 PSTxMgmtPacket
127 s_MgrMakeReAssocRequest(
128         PSDevice pDevice,
129         PSMgmtObject pMgmt,
130         unsigned char *pDAddr,
131         unsigned short wCurrCapInfo,
132         unsigned short wListenInterval,
133         PWLAN_IE_SSID pCurrSSID,
134         PWLAN_IE_SUPP_RATES pCurrRates,
135         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
136 );
137
138 static
139 void
140 s_vMgrRxAssocResponse(
141         PSDevice pDevice,
142         PSMgmtObject pMgmt,
143         PSRxMgmtPacket pRxPacket,
144         bool bReAssocType
145 );
146
147 static
148 void
149 s_vMgrRxDisassociation(
150         PSDevice pDevice,
151         PSMgmtObject pMgmt,
152         PSRxMgmtPacket pRxPacket
153 );
154
155 // Authentication/deauthen functions
156 static
157 void
158 s_vMgrRxAuthenSequence_1(
159         PSDevice pDevice,
160         PSMgmtObject pMgmt,
161         PWLAN_FR_AUTHEN pFrame
162 );
163
164 static
165 void
166 s_vMgrRxAuthenSequence_2(
167         PSDevice pDevice,
168         PSMgmtObject pMgmt,
169         PWLAN_FR_AUTHEN pFrame
170 );
171
172 static
173 void
174 s_vMgrRxAuthenSequence_3(
175         PSDevice pDevice,
176         PSMgmtObject pMgmt,
177         PWLAN_FR_AUTHEN pFrame
178 );
179
180 static
181 void
182 s_vMgrRxAuthenSequence_4(
183         PSDevice pDevice,
184         PSMgmtObject pMgmt,
185         PWLAN_FR_AUTHEN pFrame
186 );
187
188 static
189 void
190 s_vMgrRxAuthentication(
191         PSDevice pDevice,
192         PSMgmtObject pMgmt,
193         PSRxMgmtPacket pRxPacket
194 );
195
196 static
197 void
198 s_vMgrRxDeauthentication(
199         PSDevice pDevice,
200         PSMgmtObject pMgmt,
201         PSRxMgmtPacket pRxPacket
202 );
203
204 // Scan functions
205 // probe request/response functions
206 static
207 void
208 s_vMgrRxProbeRequest(
209         PSDevice pDevice,
210         PSMgmtObject pMgmt,
211         PSRxMgmtPacket pRxPacket
212 );
213
214 static
215 void
216 s_vMgrRxProbeResponse(
217         PSDevice pDevice,
218         PSMgmtObject pMgmt,
219         PSRxMgmtPacket pRxPacket
220 );
221
222 // beacon functions
223 static
224 void
225 s_vMgrRxBeacon(
226         PSDevice pDevice,
227         PSMgmtObject pMgmt,
228         PSRxMgmtPacket pRxPacket,
229         bool bInScan
230 );
231
232 static
233 void
234 s_vMgrFormatTIM(
235         PSMgmtObject pMgmt,
236         PWLAN_IE_TIM pTIM
237 );
238
239 static
240 PSTxMgmtPacket
241 s_MgrMakeBeacon(
242         PSDevice pDevice,
243         PSMgmtObject pMgmt,
244         unsigned short wCurrCapInfo,
245         unsigned short wCurrBeaconPeriod,
246         unsigned int uCurrChannel,
247         unsigned short wCurrATIMWinodw,
248         PWLAN_IE_SSID pCurrSSID,
249         unsigned char *pCurrBSSID,
250         PWLAN_IE_SUPP_RATES pCurrSuppRates,
251         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
252 );
253
254
255 // Association response
256 static
257 PSTxMgmtPacket
258 s_MgrMakeAssocResponse(
259         PSDevice pDevice,
260         PSMgmtObject pMgmt,
261         unsigned short wCurrCapInfo,
262         unsigned short wAssocStatus,
263         unsigned short wAssocAID,
264         unsigned char *pDstAddr,
265         PWLAN_IE_SUPP_RATES pCurrSuppRates,
266         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
267 );
268
269 // ReAssociation response
270 static
271 PSTxMgmtPacket
272 s_MgrMakeReAssocResponse(
273         PSDevice pDevice,
274         PSMgmtObject pMgmt,
275         unsigned short wCurrCapInfo,
276         unsigned short wAssocStatus,
277         unsigned short wAssocAID,
278         unsigned char *pDstAddr,
279         PWLAN_IE_SUPP_RATES pCurrSuppRates,
280         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
281 );
282
283 // Probe response
284 static
285 PSTxMgmtPacket
286 s_MgrMakeProbeResponse(
287         PSDevice pDevice,
288         PSMgmtObject pMgmt,
289         unsigned short wCurrCapInfo,
290         unsigned short wCurrBeaconPeriod,
291         unsigned int uCurrChannel,
292         unsigned short wCurrATIMWinodw,
293         unsigned char *pDstAddr,
294         PWLAN_IE_SSID pCurrSSID,
295         unsigned char *pCurrBSSID,
296         PWLAN_IE_SUPP_RATES pCurrSuppRates,
297         PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
298         unsigned char byPHYType
299 );
300
301 // received status
302 static
303 void
304 s_vMgrLogStatus(
305         PSMgmtObject pMgmt,
306         unsigned short wStatus
307 );
308
309
310 static
311 void
312 s_vMgrSynchBSS(
313         PSDevice      pDevice,
314         unsigned int uBSSMode,
315         PKnownBSS     pCurr,
316         PCMD_STATUS  pStatus
317 );
318
319
320 static bool
321 s_bCipherMatch(
322         PKnownBSS                        pBSSNode,
323         NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
324         unsigned char *pbyCCSPK,
325         unsigned char *pbyCCSGK
326 );
327
328 static void  Encyption_Rebuild(
329         PSDevice pDevice,
330         PKnownBSS pCurr
331 );
332
333
334
335 /*---------------------  Export Variables  --------------------------*/
336
337
338 /*---------------------  Export Functions  --------------------------*/
339
340
341 /*+
342  *
343  * Routine Description:
344  *    Allocates and initializes the Management object.
345  *
346  * Return Value:
347  *    Ndis_staus.
348  *
349  -*/
350
351 void
352 vMgrObjectInit(
353         void *hDeviceContext
354 )
355 {
356         PSDevice     pDevice = (PSDevice)hDeviceContext;
357         PSMgmtObject    pMgmt = pDevice->pMgmt;
358         int ii;
359
360
361         pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
362         pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
363         pMgmt->uCurrChannel = pDevice->uChannel;
364         for (ii = 0; ii < WLAN_BSSID_LEN; ii++) {
365                 pMgmt->abyDesireBSSID[ii] = 0xFF;
366         }
367         pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
368         //memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
369         pMgmt->byCSSPK = KEY_CTL_NONE;
370         pMgmt->byCSSGK = KEY_CTL_NONE;
371         pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
372         BSSvClearBSSList((void *)pDevice, false);
373
374         return;
375 }
376
377 /*+
378  *
379  * Routine Description:
380  *    Initializes timer object
381  *
382  * Return Value:
383  *    Ndis_staus.
384  *
385  -*/
386
387 void
388 vMgrTimerInit(
389         void *hDeviceContext
390 )
391 {
392         PSDevice     pDevice = (PSDevice)hDeviceContext;
393         PSMgmtObject    pMgmt = pDevice->pMgmt;
394
395
396         init_timer(&pMgmt->sTimerSecondCallback);
397         pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice;
398         pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
399         pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
400
401         init_timer(&pDevice->sTimerCommand);
402         pDevice->sTimerCommand.data = (unsigned long) pDevice;
403         pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
404         pDevice->sTimerCommand.expires = RUN_AT(HZ);
405
406 #ifdef TxInSleep
407         init_timer(&pDevice->sTimerTxData);
408         pDevice->sTimerTxData.data = (unsigned long) pDevice;
409         pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
410         pDevice->sTimerTxData.expires = RUN_AT(10*HZ);      //10s callback
411         pDevice->fTxDataInSleep = false;
412         pDevice->IsTxDataTrigger = false;
413         pDevice->nTxDataTimeCout = 0;
414 #endif
415
416         pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
417         pDevice->uCmdDequeueIdx = 0;
418         pDevice->uCmdEnqueueIdx = 0;
419
420         return;
421 }
422
423
424
425 /*+
426  *
427  * Routine Description:
428  *    Reset the management object structure.
429  *
430  * Return Value:
431  *    None.
432  *
433  -*/
434
435 void
436 vMgrObjectReset(
437         void *hDeviceContext
438 )
439 {
440         PSDevice         pDevice = (PSDevice)hDeviceContext;
441         PSMgmtObject        pMgmt = pDevice->pMgmt;
442
443         pMgmt->eCurrMode = WMAC_MODE_STANDBY;
444         pMgmt->eCurrState = WMAC_STATE_IDLE;
445         pDevice->bEnablePSMode = false;
446         // TODO: timer
447
448         return;
449 }
450
451
452 /*+
453  *
454  * Routine Description:
455  *    Start the station association procedure.  Namely, send an
456  *    association request frame to the AP.
457  *
458  * Return Value:
459  *    None.
460  *
461  -*/
462
463
464 void
465 vMgrAssocBeginSta(
466         void *hDeviceContext,
467         PSMgmtObject pMgmt,
468         PCMD_STATUS pStatus
469 )
470 {
471         PSDevice             pDevice = (PSDevice)hDeviceContext;
472         PSTxMgmtPacket          pTxPacket;
473
474
475         pMgmt->wCurrCapInfo = 0;
476         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
477         if (pDevice->bEncryptionEnable) {
478                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
479         }
480         // always allow receive short preamble
481         //if (pDevice->byPreambleType == 1) {
482         //    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
483         //}
484         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
485         if (pMgmt->wListenInterval == 0)
486                 pMgmt->wListenInterval = 1;    // at least one.
487
488         // ERP Phy (802.11g) should support short preamble.
489         if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
490                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
491                 if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) {
492                         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
493                 }
494         } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
495                 if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) {
496                         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
497                 }
498         }
499         if (pMgmt->b11hEnable == true)
500                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
501
502         /* build an assocreq frame and send it */
503         pTxPacket = s_MgrMakeAssocRequest
504                 (
505                         pDevice,
506                         pMgmt,
507                         pMgmt->abyCurrBSSID,
508                         pMgmt->wCurrCapInfo,
509                         pMgmt->wListenInterval,
510                         (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
511                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
512                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
513 );
514
515         if (pTxPacket != NULL) {
516                 /* send the frame */
517                 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
518                 if (*pStatus == CMD_STATUS_PENDING) {
519                         pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
520                         *pStatus = CMD_STATUS_SUCCESS;
521                 }
522         }
523         else
524                 *pStatus = CMD_STATUS_RESOURCES;
525
526         return;
527 }
528
529
530 /*+
531  *
532  * Routine Description:
533  *    Start the station re-association procedure.
534  *
535  * Return Value:
536  *    None.
537  *
538  -*/
539
540 void
541 vMgrReAssocBeginSta(
542         void *hDeviceContext,
543         PSMgmtObject pMgmt,
544         PCMD_STATUS pStatus
545 )
546 {
547         PSDevice             pDevice = (PSDevice)hDeviceContext;
548         PSTxMgmtPacket          pTxPacket;
549
550
551
552         pMgmt->wCurrCapInfo = 0;
553         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
554         if (pDevice->bEncryptionEnable) {
555                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
556         }
557
558         //if (pDevice->byPreambleType == 1) {
559         //    pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
560         //}
561         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
562
563         if (pMgmt->wListenInterval == 0)
564                 pMgmt->wListenInterval = 1;    // at least one.
565
566
567         // ERP Phy (802.11g) should support short preamble.
568         if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
569                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
570                 if (CARDbIsShorSlotTime(pMgmt->pAdapter) == true) {
571                         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
572                 }
573         } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
574                 if (CARDbIsShortPreamble(pMgmt->pAdapter) == true) {
575                         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
576                 }
577         }
578         if (pMgmt->b11hEnable == true)
579                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
580
581
582         pTxPacket = s_MgrMakeReAssocRequest
583                 (
584                         pDevice,
585                         pMgmt,
586                         pMgmt->abyCurrBSSID,
587                         pMgmt->wCurrCapInfo,
588                         pMgmt->wListenInterval,
589                         (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
590                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
591                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
592 );
593
594         if (pTxPacket != NULL) {
595                 /* send the frame */
596                 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
597                 if (*pStatus != CMD_STATUS_PENDING) {
598                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
599                 }
600                 else {
601                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
602                 }
603         }
604
605
606         return;
607 }
608
609 /*+
610  *
611  * Routine Description:
612  *    Send an dis-association request frame to the AP.
613  *
614  * Return Value:
615  *    None.
616  *
617  -*/
618
619 void
620 vMgrDisassocBeginSta(
621         void *hDeviceContext,
622         PSMgmtObject pMgmt,
623         unsigned char *abyDestAddress,
624         unsigned short wReason,
625         PCMD_STATUS pStatus
626 )
627 {
628         PSDevice            pDevice = (PSDevice)hDeviceContext;
629         PSTxMgmtPacket      pTxPacket = NULL;
630         WLAN_FR_DISASSOC    sFrame;
631
632         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
633         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
634         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
635
636         // Setup the sFrame structure
637         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
638         sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
639
640         // format fixed field frame structure
641         vMgrEncodeDisassociation(&sFrame);
642
643         // Setup the header
644         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
645                 (
646                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
647                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
648 ));
649
650         memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
651         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
652         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
653
654         // Set reason code
655         *(sFrame.pwReason) = cpu_to_le16(wReason);
656         pTxPacket->cbMPDULen = sFrame.len;
657         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
658
659         // send the frame
660         *pStatus = csMgmt_xmit(pDevice, pTxPacket);
661         if (*pStatus == CMD_STATUS_PENDING) {
662                 pMgmt->eCurrState = WMAC_STATE_IDLE;
663                 *pStatus = CMD_STATUS_SUCCESS;
664         }
665
666         return;
667 }
668
669
670
671 /*+
672  *
673  * Routine Description:(AP function)
674  *    Handle incoming station association request frames.
675  *
676  * Return Value:
677  *    None.
678  *
679  -*/
680
681 static
682 void
683 s_vMgrRxAssocRequest(
684         PSDevice pDevice,
685         PSMgmtObject pMgmt,
686         PSRxMgmtPacket pRxPacket,
687         unsigned int uNodeIndex
688 )
689 {
690         WLAN_FR_ASSOCREQ    sFrame;
691         CMD_STATUS          Status;
692         PSTxMgmtPacket      pTxPacket;
693         unsigned short wAssocStatus = 0;
694         unsigned short wAssocAID = 0;
695         unsigned int uRateLen = WLAN_RATES_MAXLEN;
696         unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
697         unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
698
699
700         if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
701                 return;
702         //  node index not found
703         if (!uNodeIndex)
704                 return;
705
706         //check if node is authenticated
707         //decode the frame
708         memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
709         memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
710         memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
711         sFrame.len = pRxPacket->cbMPDULen;
712         sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
713
714         vMgrDecodeAssocRequest(&sFrame);
715
716         if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
717                 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
718                 pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
719                 pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
720                 pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
721                         WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
722                 // Todo: check sta basic rate, if ap can't support, set status code
723                 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
724                         uRateLen = WLAN_RATES_MAXLEN_11B;
725                 }
726                 abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
727                 abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
728                                                  (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
729                                                  uRateLen);
730                 abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
731                 if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
732                         abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
733                                                             (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
734                                                             uRateLen);
735                 } else {
736                         abyCurrExtSuppRates[1] = 0;
737                 }
738
739
740                 RATEvParseMaxRate((void *)pDevice,
741                                   (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
742                                   (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
743                                   false, // do not change our basic rate
744                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
745                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
746                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
747                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
748                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
749 );
750
751                 // set max tx rate
752                 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
753                         pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
754 #ifdef  PLICE_DEBUG
755                 printk("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
756 #endif
757                 // Todo: check sta preamble, if ap can't support, set status code
758                 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
759                         WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
760                 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
761                         WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
762                 pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
763                 wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
764                 wAssocAID = (unsigned short)uNodeIndex;
765                 // check if ERP support
766                 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
767                         pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
768
769                 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
770                         // B only STA join
771                         pDevice->bProtectMode = true;
772                         pDevice->bNonERPPresent = true;
773                 }
774                 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
775                         pDevice->bBarkerPreambleMd = true;
776                 }
777
778                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
779                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
780                         sFrame.pHdr->sA3.abyAddr2[0],
781                         sFrame.pHdr->sA3.abyAddr2[1],
782                         sFrame.pHdr->sA3.abyAddr2[2],
783                         sFrame.pHdr->sA3.abyAddr2[3],
784                         sFrame.pHdr->sA3.abyAddr2[4],
785                         sFrame.pHdr->sA3.abyAddr2[5]
786                         );
787                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
788                         pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
789         }//else { TODO: received STA under state1 handle }
790         else {
791                 return;
792         }
793
794
795         // assoc response reply..
796         pTxPacket = s_MgrMakeAssocResponse
797                 (
798                         pDevice,
799                         pMgmt,
800                         pMgmt->wCurrCapInfo,
801                         wAssocStatus,
802                         wAssocAID,
803                         sFrame.pHdr->sA3.abyAddr2,
804                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
805                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
806 );
807         if (pTxPacket != NULL) {
808
809                 if (pDevice->bEnableHostapd) {
810                         return;
811                 }
812                 /* send the frame */
813                 Status = csMgmt_xmit(pDevice, pTxPacket);
814                 if (Status != CMD_STATUS_PENDING) {
815                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
816                 }
817                 else {
818                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
819                 }
820
821         }
822
823         return;
824 }
825
826
827 /*+
828  *
829  * Description:(AP function)
830  *      Handle incoming station re-association request frames.
831  *
832  * Parameters:
833  *  In:
834  *      pMgmt           - Management Object structure
835  *      pRxPacket       - Received Packet
836  *  Out:
837  *      none
838  *
839  * Return Value: None.
840  *
841  -*/
842
843 static
844 void
845 s_vMgrRxReAssocRequest(
846         PSDevice pDevice,
847         PSMgmtObject pMgmt,
848         PSRxMgmtPacket pRxPacket,
849         unsigned int uNodeIndex
850 )
851 {
852         WLAN_FR_REASSOCREQ    sFrame;
853         CMD_STATUS          Status;
854         PSTxMgmtPacket      pTxPacket;
855         unsigned short wAssocStatus = 0;
856         unsigned short wAssocAID = 0;
857         unsigned int    uRateLen = WLAN_RATES_MAXLEN;
858         unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
859         unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
860
861         if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
862                 return;
863         //  node index not found
864         if (!uNodeIndex)
865                 return;
866         //check if node is authenticated
867         //decode the frame
868         memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
869         sFrame.len = pRxPacket->cbMPDULen;
870         sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
871         vMgrDecodeReassocRequest(&sFrame);
872
873         if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
874                 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
875                 pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
876                 pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
877                 pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
878                         WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
879                 // Todo: check sta basic rate, if ap can't support, set status code
880
881                 if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
882                         uRateLen = WLAN_RATES_MAXLEN_11B;
883                 }
884
885                 abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
886                 abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
887                                                  (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
888                                                  uRateLen);
889                 abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
890                 if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
891                         abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
892                                                             (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
893                                                             uRateLen);
894                 } else {
895                         abyCurrExtSuppRates[1] = 0;
896                 }
897
898
899                 RATEvParseMaxRate((void *)pDevice,
900                                   (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
901                                   (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
902                                   false, // do not change our basic rate
903                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
904                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
905                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
906                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
907                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
908 );
909
910                 // set max tx rate
911                 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
912                         pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
913 #ifdef  PLICE_DEBUG
914                 printk("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
915 #endif
916                 // Todo: check sta preamble, if ap can't support, set status code
917                 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
918                         WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
919                 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
920                         WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
921                 pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
922                 wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
923                 wAssocAID = (unsigned short)uNodeIndex;
924
925                 // if suppurt ERP
926                 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
927                         pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
928
929                 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
930                         // B only STA join
931                         pDevice->bProtectMode = true;
932                         pDevice->bNonERPPresent = true;
933                 }
934                 if (pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble == false) {
935                         pDevice->bBarkerPreambleMd = true;
936                 }
937
938                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
939                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
940                         sFrame.pHdr->sA3.abyAddr2[0],
941                         sFrame.pHdr->sA3.abyAddr2[1],
942                         sFrame.pHdr->sA3.abyAddr2[2],
943                         sFrame.pHdr->sA3.abyAddr2[3],
944                         sFrame.pHdr->sA3.abyAddr2[4],
945                         sFrame.pHdr->sA3.abyAddr2[5]
946                         );
947                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
948                         pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
949
950         }
951
952
953         // assoc response reply..
954         pTxPacket = s_MgrMakeReAssocResponse
955                 (
956                         pDevice,
957                         pMgmt,
958                         pMgmt->wCurrCapInfo,
959                         wAssocStatus,
960                         wAssocAID,
961                         sFrame.pHdr->sA3.abyAddr2,
962                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
963                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
964                         );
965
966         if (pTxPacket != NULL) {
967                 /* send the frame */
968                 if (pDevice->bEnableHostapd) {
969                         return;
970                 }
971                 Status = csMgmt_xmit(pDevice, pTxPacket);
972                 if (Status != CMD_STATUS_PENDING) {
973                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
974                 }
975                 else {
976                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
977                 }
978         }
979         return;
980 }
981
982
983 /*+
984  *
985  * Routine Description:
986  *    Handle incoming association response frames.
987  *
988  * Return Value:
989  *    None.
990  *
991  -*/
992
993 static
994 void
995 s_vMgrRxAssocResponse(
996         PSDevice pDevice,
997         PSMgmtObject pMgmt,
998         PSRxMgmtPacket pRxPacket,
999         bool bReAssocType
1000 )
1001 {
1002         WLAN_FR_ASSOCRESP   sFrame;
1003         PWLAN_IE_SSID   pItemSSID;
1004         unsigned char *pbyIEs;
1005         viawget_wpa_header *wpahdr;
1006
1007
1008
1009         if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
1010             pMgmt->eCurrState == WMAC_STATE_ASSOC) {
1011
1012                 sFrame.len = pRxPacket->cbMPDULen;
1013                 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1014                 // decode the frame
1015                 vMgrDecodeAssocResponse(&sFrame);
1016                 if ((sFrame.pwCapInfo == 0) ||
1017                     (sFrame.pwStatus == 0) ||
1018                     (sFrame.pwAid == 0) ||
1019                     (sFrame.pSuppRates == 0)) {
1020                         DBG_PORT80(0xCC);
1021                         return;
1022                 }
1023
1024                 pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
1025                 pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
1026                 pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid);
1027                 pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07;
1028
1029                 pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6;
1030                 pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1031                 pbyIEs = pMgmt->sAssocInfo.abyIEs;
1032                 pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1033                 memcpy(pbyIEs, (sFrame.pBuf + 24 + 6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength);
1034
1035                 // save values and set current BSS state
1036                 if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1037                         // set AID
1038                         pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
1039                         if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1))
1040                         {
1041                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
1042                         }
1043                         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14 | BIT15));
1044                         pMgmt->eCurrState = WMAC_STATE_ASSOC;
1045                         BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
1046                         pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
1047                         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
1048                         pDevice->bLinkPass = true;
1049                         pDevice->uBBVGADiffCount = 0;
1050                         if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1051                                 if (skb_tailroom(pDevice->skb) < (sizeof(viawget_wpa_header) + pMgmt->sAssocInfo.AssocInfo.ResponseIELength +
1052                                                                   pMgmt->sAssocInfo.AssocInfo.RequestIELength)) {    //data room not enough
1053                                         dev_kfree_skb(pDevice->skb);
1054                                         pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1055                                 }
1056                                 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1057                                 wpahdr->type = VIAWGET_ASSOC_MSG;
1058                                 wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
1059                                 wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1060                                 memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len);
1061                                 memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len,
1062                                        pbyIEs,
1063                                        wpahdr->resp_ie_len
1064 );
1065                                 skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
1066                                 pDevice->skb->dev = pDevice->wpadev;
1067                                 skb_reset_mac_header(pDevice->skb);
1068                                 pDevice->skb->pkt_type = PACKET_HOST;
1069                                 pDevice->skb->protocol = htons(ETH_P_802_2);
1070                                 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1071                                 netif_rx(pDevice->skb);
1072                                 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1073                         }
1074
1075 //2008-0409-07, <Add> by Einsn Liu
1076 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1077                         //if (pDevice->bWPADevEnable == true)
1078                         {
1079                                 unsigned char buf[512];
1080                                 size_t len;
1081                                 union iwreq_data  wrqu;
1082                                 int we_event;
1083
1084                                 memset(buf, 0, 512);
1085
1086                                 len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1087                                 if (len)        {
1088                                         memcpy(buf, pMgmt->sAssocInfo.abyIEs, len);
1089                                         memset(&wrqu, 0, sizeof(wrqu));
1090                                         wrqu.data.length = len;
1091                                         we_event = IWEVASSOCREQIE;
1092                                         wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
1093                                 }
1094
1095                                 memset(buf, 0, 512);
1096                                 len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
1097
1098                                 if (len)        {
1099                                         memcpy(buf, pbyIEs, len);
1100                                         memset(&wrqu, 0, sizeof(wrqu));
1101                                         wrqu.data.length = len;
1102                                         we_event = IWEVASSOCRESPIE;
1103                                         wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
1104                                 }
1105
1106
1107                                 memset(&wrqu, 0, sizeof(wrqu));
1108                                 memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN);
1109                                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1110                                 wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1111                         }
1112 #endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1113 //End Add -- //2008-0409-07, <Add> by Einsn Liu
1114                 }
1115                 else {
1116                         if (bReAssocType) {
1117                                 pMgmt->eCurrState = WMAC_STATE_IDLE;
1118                         }
1119                         else {
1120                                 // jump back to the auth state and indicate the error
1121                                 pMgmt->eCurrState = WMAC_STATE_AUTH;
1122                         }
1123                         s_vMgrLogStatus(pMgmt, cpu_to_le16((*(sFrame.pwStatus))));
1124                 }
1125
1126         }
1127
1128 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1129 //need clear flags related to Networkmanager
1130
1131         pDevice->bwextcount = 0;
1132         pDevice->bWPASuppWextEnabled = false;
1133 #endif
1134
1135
1136         if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
1137                 timer_expire(pDevice->sTimerCommand, 0);
1138         return;
1139 }
1140
1141
1142
1143 /*+
1144  *
1145  * Routine Description:
1146  *    Start the station authentication procedure.  Namely, send an
1147  *    authentication frame to the AP.
1148  *
1149  * Return Value:
1150  *    None.
1151  *
1152  -*/
1153
1154 void
1155 vMgrAuthenBeginSta(
1156         void *hDeviceContext,
1157         PSMgmtObject  pMgmt,
1158         PCMD_STATUS pStatus
1159 )
1160 {
1161         PSDevice     pDevice = (PSDevice)hDeviceContext;
1162         WLAN_FR_AUTHEN  sFrame;
1163         PSTxMgmtPacket  pTxPacket = NULL;
1164
1165         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1166         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1167         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1168         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1169         sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1170         vMgrEncodeAuthen(&sFrame);
1171         /* insert values */
1172         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1173                 (
1174                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1175                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)
1176 ));
1177         memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
1178         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1179         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1180         if (pMgmt->bShareKeyAlgorithm)
1181                 *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY);
1182         else
1183                 *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM);
1184
1185         *(sFrame.pwAuthSequence) = cpu_to_le16(1);
1186         /* Adjust the length fields */
1187         pTxPacket->cbMPDULen = sFrame.len;
1188         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1189
1190         *pStatus = csMgmt_xmit(pDevice, pTxPacket);
1191         if (*pStatus == CMD_STATUS_PENDING) {
1192                 pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
1193                 *pStatus = CMD_STATUS_SUCCESS;
1194         }
1195
1196         return;
1197 }
1198
1199
1200
1201 /*+
1202  *
1203  * Routine Description:
1204  *    Start the station(AP) deauthentication procedure.  Namely, send an
1205  *    deauthentication frame to the AP or Sta.
1206  *
1207  * Return Value:
1208  *    None.
1209  *
1210  -*/
1211
1212 void
1213 vMgrDeAuthenBeginSta(
1214         void *hDeviceContext,
1215         PSMgmtObject  pMgmt,
1216         unsigned char *abyDestAddress,
1217         unsigned short wReason,
1218         PCMD_STATUS pStatus
1219 )
1220 {
1221         PSDevice            pDevice = (PSDevice)hDeviceContext;
1222         WLAN_FR_DEAUTHEN    sFrame;
1223         PSTxMgmtPacket      pTxPacket = NULL;
1224
1225
1226         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1227         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN);
1228         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1229         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1230         sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
1231         vMgrEncodeDeauthen(&sFrame);
1232         /* insert values */
1233         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1234                 (
1235                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1236                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN)
1237 ));
1238
1239         memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
1240         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1241         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1242
1243         *(sFrame.pwReason) = cpu_to_le16(wReason);       // deauthen. bcs left BSS
1244         /* Adjust the length fields */
1245         pTxPacket->cbMPDULen = sFrame.len;
1246         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1247
1248         *pStatus = csMgmt_xmit(pDevice, pTxPacket);
1249         if (*pStatus == CMD_STATUS_PENDING) {
1250                 *pStatus = CMD_STATUS_SUCCESS;
1251         }
1252
1253
1254         return;
1255 }
1256
1257
1258 /*+
1259  *
1260  * Routine Description:
1261  *    Handle incoming authentication frames.
1262  *
1263  * Return Value:
1264  *    None.
1265  *
1266  -*/
1267
1268 static
1269 void
1270 s_vMgrRxAuthentication(
1271         PSDevice pDevice,
1272         PSMgmtObject pMgmt,
1273         PSRxMgmtPacket pRxPacket
1274 )
1275 {
1276         WLAN_FR_AUTHEN  sFrame;
1277
1278         // we better be an AP or a STA in AUTHPENDING otherwise ignore
1279         if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP ||
1280               pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) {
1281                 return;
1282         }
1283
1284         // decode the frame
1285         sFrame.len = pRxPacket->cbMPDULen;
1286         sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1287         vMgrDecodeAuthen(&sFrame);
1288         switch (cpu_to_le16((*(sFrame.pwAuthSequence)))) {
1289         case 1:
1290                 //AP function
1291                 s_vMgrRxAuthenSequence_1(pDevice, pMgmt, &sFrame);
1292                 break;
1293         case 2:
1294                 s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame);
1295                 break;
1296         case 3:
1297                 //AP function
1298                 s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame);
1299                 break;
1300         case 4:
1301                 s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
1302                 break;
1303         default:
1304                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
1305                         cpu_to_le16((*(sFrame.pwAuthSequence))));
1306                 break;
1307         }
1308         return;
1309 }
1310
1311
1312
1313 /*+
1314  *
1315  * Routine Description:
1316  *   Handles incoming authen frames with sequence 1.  Currently
1317  *   assumes we're an AP.  So far, no one appears to use authentication
1318  *   in Ad-Hoc mode.
1319  *
1320  * Return Value:
1321  *    None.
1322  *
1323  -*/
1324
1325
1326 static
1327 void
1328 s_vMgrRxAuthenSequence_1(
1329         PSDevice pDevice,
1330         PSMgmtObject pMgmt,
1331         PWLAN_FR_AUTHEN pFrame
1332 )
1333 {
1334         PSTxMgmtPacket      pTxPacket = NULL;
1335         unsigned int    uNodeIndex;
1336         WLAN_FR_AUTHEN      sFrame;
1337         PSKeyItem           pTransmitKey;
1338
1339         // Insert a Node entry
1340         if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
1341                 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
1342                 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2,
1343                        WLAN_ADDR_LEN);
1344         }
1345
1346         if (pMgmt->bShareKeyAlgorithm) {
1347                 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN;
1348                 pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1;
1349         }
1350         else {
1351                 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
1352         }
1353
1354         // send auth reply
1355         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1356         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1357         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1358         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1359         sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1360         // format buffer structure
1361         vMgrEncodeAuthen(&sFrame);
1362         // insert values
1363         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1364                 (
1365                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1366                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1367                         WLAN_SET_FC_ISWEP(0)
1368 ));
1369         memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
1370         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1371         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1372         *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1373         *(sFrame.pwAuthSequence) = cpu_to_le16(2);
1374
1375         if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) {
1376                 if (pMgmt->bShareKeyAlgorithm)
1377                         *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1378                 else
1379                         *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
1380         }
1381         else {
1382                 if (pMgmt->bShareKeyAlgorithm)
1383                         *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
1384                 else
1385                         *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1386         }
1387
1388         if (pMgmt->bShareKeyAlgorithm &&
1389             (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) {
1390
1391                 sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
1392                 sFrame.len += WLAN_CHALLENGE_IE_LEN;
1393                 sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
1394                 sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
1395                 memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
1396                 // get group key
1397                 if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) {
1398                         rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
1399                         rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
1400                 }
1401                 memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN);
1402         }
1403
1404         /* Adjust the length fields */
1405         pTxPacket->cbMPDULen = sFrame.len;
1406         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1407         // send the frame
1408         if (pDevice->bEnableHostapd) {
1409                 return;
1410         }
1411         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
1412         if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
1413                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
1414         }
1415         return;
1416 }
1417
1418
1419
1420 /*+
1421  *
1422  * Routine Description:
1423  *   Handles incoming auth frames with sequence number 2.  Currently
1424  *   assumes we're a station.
1425  *
1426  *
1427  * Return Value:
1428  *    None.
1429  *
1430  -*/
1431
1432 static
1433 void
1434 s_vMgrRxAuthenSequence_2(
1435         PSDevice pDevice,
1436         PSMgmtObject pMgmt,
1437         PWLAN_FR_AUTHEN pFrame
1438 )
1439 {
1440         WLAN_FR_AUTHEN      sFrame;
1441         PSTxMgmtPacket      pTxPacket = NULL;
1442
1443
1444         switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm))))
1445         {
1446         case WLAN_AUTH_ALG_OPENSYSTEM:
1447                 if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1448                         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
1449                         pMgmt->eCurrState = WMAC_STATE_AUTH;
1450                         timer_expire(pDevice->sTimerCommand, 0);
1451                 }
1452                 else {
1453                         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
1454                         s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1455                         pMgmt->eCurrState = WMAC_STATE_IDLE;
1456                 }
1457                 if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
1458 //                spin_unlock_irq(&pDevice->lock);
1459 //                vCommandTimerWait((void *)pDevice, 0);
1460 //                spin_lock_irq(&pDevice->lock);
1461                 }
1462
1463                 break;
1464
1465         case WLAN_AUTH_ALG_SHAREDKEY:
1466
1467                 if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1468                         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1469                         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1470                         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1471                         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1472                         sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1473                         // format buffer structure
1474                         vMgrEncodeAuthen(&sFrame);
1475                         // insert values
1476                         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1477                                 (
1478                                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1479                                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1480                                         WLAN_SET_FC_ISWEP(1)
1481 ));
1482                         memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1483                         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1484                         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1485                         *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1486                         *(sFrame.pwAuthSequence) = cpu_to_le16(3);
1487                         *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1488                         sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
1489                         sFrame.len += WLAN_CHALLENGE_IE_LEN;
1490                         sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
1491                         sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
1492                         memcpy(sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN);
1493                         // Adjust the length fields
1494                         pTxPacket->cbMPDULen = sFrame.len;
1495                         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1496                         // send the frame
1497                         if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
1498                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
1499                         }
1500                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
1501                 }
1502                 else {
1503                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
1504                         if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
1505 //                    spin_unlock_irq(&pDevice->lock);
1506 //                    vCommandTimerWait((void *)pDevice, 0);
1507 //                    spin_lock_irq(&pDevice->lock);
1508                         }
1509                         s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1510                 }
1511                 break;
1512         default:
1513                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
1514                 break;
1515         }
1516         return;
1517 }
1518
1519
1520
1521 /*+
1522  *
1523  * Routine Description:
1524  *   Handles incoming authen frames with sequence 3.  Currently
1525  *   assumes we're an AP.  This function assumes the frame has
1526  *   already been successfully decrypted.
1527  *
1528  *
1529  * Return Value:
1530  *    None.
1531  *
1532  -*/
1533
1534 static
1535 void
1536 s_vMgrRxAuthenSequence_3(
1537         PSDevice pDevice,
1538         PSMgmtObject pMgmt,
1539         PWLAN_FR_AUTHEN pFrame
1540 )
1541 {
1542         PSTxMgmtPacket      pTxPacket = NULL;
1543         unsigned int uStatusCode = 0;
1544         unsigned int uNodeIndex = 0;
1545         WLAN_FR_AUTHEN      sFrame;
1546
1547         if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
1548                 uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
1549                 goto reply;
1550         }
1551         if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
1552                 if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) {
1553                         uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ;
1554                         goto reply;
1555                 }
1556                 if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) {
1557                         uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
1558                         goto reply;
1559                 }
1560         }
1561         else {
1562                 uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE;
1563                 goto reply;
1564         }
1565
1566         if (uNodeIndex) {
1567                 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
1568                 pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
1569         }
1570         uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
1571         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
1572
1573 reply:
1574         // send auth reply
1575         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1576         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1577         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1578         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1579         sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1580         // format buffer structure
1581         vMgrEncodeAuthen(&sFrame);
1582         /* insert values */
1583         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1584                 (
1585                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1586                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1587                         WLAN_SET_FC_ISWEP(0)
1588 ));
1589         memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
1590         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1591         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1592         *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1593         *(sFrame.pwAuthSequence) = cpu_to_le16(4);
1594         *(sFrame.pwStatus) = cpu_to_le16(uStatusCode);
1595
1596         /* Adjust the length fields */
1597         pTxPacket->cbMPDULen = sFrame.len;
1598         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1599         // send the frame
1600         if (pDevice->bEnableHostapd) {
1601                 return;
1602         }
1603         if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) {
1604                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
1605         }
1606         return;
1607
1608 }
1609
1610
1611
1612 /*+
1613  *
1614  * Routine Description:
1615  *   Handles incoming authen frames with sequence 4
1616  *
1617  *
1618  * Return Value:
1619  *    None.
1620  *
1621  -*/
1622 static
1623 void
1624 s_vMgrRxAuthenSequence_4(
1625         PSDevice pDevice,
1626         PSMgmtObject pMgmt,
1627         PWLAN_FR_AUTHEN pFrame
1628 )
1629 {
1630
1631         if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1632                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
1633                 pMgmt->eCurrState = WMAC_STATE_AUTH;
1634                 timer_expire(pDevice->sTimerCommand, 0);
1635         }
1636         else{
1637                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
1638                 s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1639                 pMgmt->eCurrState = WMAC_STATE_IDLE;
1640         }
1641
1642         if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) {
1643 //        spin_unlock_irq(&pDevice->lock);
1644 //        vCommandTimerWait((void *)pDevice, 0);
1645 //        spin_lock_irq(&pDevice->lock);
1646         }
1647
1648 }
1649
1650 /*+
1651  *
1652  * Routine Description:
1653  *   Handles incoming disassociation frames
1654  *
1655  *
1656  * Return Value:
1657  *    None.
1658  *
1659  -*/
1660
1661 static
1662 void
1663 s_vMgrRxDisassociation(
1664         PSDevice pDevice,
1665         PSMgmtObject pMgmt,
1666         PSRxMgmtPacket pRxPacket
1667 )
1668 {
1669         WLAN_FR_DISASSOC    sFrame;
1670         unsigned int uNodeIndex = 0;
1671 //    CMD_STATUS          CmdStatus;
1672         viawget_wpa_header *wpahdr;
1673
1674         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1675                 // if is acting an AP..
1676                 // a STA is leaving this BSS..
1677                 sFrame.len = pRxPacket->cbMPDULen;
1678                 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1679                 if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
1680                         BSSvRemoveOneNode(pDevice, uNodeIndex);
1681                 }
1682                 else {
1683                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
1684                 }
1685         }
1686         else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1687                 sFrame.len = pRxPacket->cbMPDULen;
1688                 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1689                 vMgrDecodeDisassociation(&sFrame);
1690                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
1691                 //TODO: do something let upper layer know or
1692                 //try to send associate packet again because of inactivity timeout
1693                 //  if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
1694                 //     vMgrReAssocBeginSta((PSDevice)pDevice, pMgmt, &CmdStatus);
1695                 //  }
1696                 if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1697                         wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1698                         wpahdr->type = VIAWGET_DISASSOC_MSG;
1699                         wpahdr->resp_ie_len = 0;
1700                         wpahdr->req_ie_len = 0;
1701                         skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1702                         pDevice->skb->dev = pDevice->wpadev;
1703                         skb_reset_mac_header(pDevice->skb);
1704
1705                         pDevice->skb->pkt_type = PACKET_HOST;
1706                         pDevice->skb->protocol = htons(ETH_P_802_2);
1707                         memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1708                         netif_rx(pDevice->skb);
1709                         pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1710                 }
1711
1712 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1713                 // if (pDevice->bWPASuppWextEnabled == true)
1714                 {
1715                         union iwreq_data  wrqu;
1716                         memset(&wrqu, 0, sizeof(wrqu));
1717                         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1718                         printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1719                         wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1720                 }
1721 #endif
1722         }
1723         /* else, ignore it */
1724
1725         return;
1726 }
1727
1728
1729 /*+
1730  *
1731  * Routine Description:
1732  *   Handles incoming deauthentication frames
1733  *
1734  *
1735  * Return Value:
1736  *    None.
1737  *
1738  -*/
1739
1740 static
1741 void
1742 s_vMgrRxDeauthentication(
1743         PSDevice pDevice,
1744         PSMgmtObject pMgmt,
1745         PSRxMgmtPacket pRxPacket
1746 )
1747 {
1748         WLAN_FR_DEAUTHEN    sFrame;
1749         unsigned int uNodeIndex = 0;
1750         viawget_wpa_header *wpahdr;
1751
1752
1753         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1754                 //Todo:
1755                 // if is acting an AP..
1756                 // a STA is leaving this BSS..
1757                 sFrame.len = pRxPacket->cbMPDULen;
1758                 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1759                 if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) {
1760                         BSSvRemoveOneNode(pDevice, uNodeIndex);
1761                 }
1762                 else {
1763                         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
1764                 }
1765         }
1766         else {
1767                 if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1768                         sFrame.len = pRxPacket->cbMPDULen;
1769                         sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1770                         vMgrDecodeDeauthen(&sFrame);
1771                         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO  "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
1772                         // TODO: update BSS list for specific BSSID if pre-authentication case
1773                         if (!compare_ether_addr(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID)) {
1774                                 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
1775                                         pMgmt->sNodeDBTable[0].bActive = false;
1776                                         pMgmt->eCurrMode = WMAC_MODE_STANDBY;
1777                                         pMgmt->eCurrState = WMAC_STATE_IDLE;
1778                                         netif_stop_queue(pDevice->dev);
1779                                         pDevice->bLinkPass = false;
1780                                 }
1781                         }
1782
1783                         if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1784                                 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1785                                 wpahdr->type = VIAWGET_DISASSOC_MSG;
1786                                 wpahdr->resp_ie_len = 0;
1787                                 wpahdr->req_ie_len = 0;
1788                                 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1789                                 pDevice->skb->dev = pDevice->wpadev;
1790                                 skb_reset_mac_header(pDevice->skb);
1791                                 pDevice->skb->pkt_type = PACKET_HOST;
1792                                 pDevice->skb->protocol = htons(ETH_P_802_2);
1793                                 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1794                                 netif_rx(pDevice->skb);
1795                                 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1796                         }
1797
1798 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1799                         // if (pDevice->bWPASuppWextEnabled == true)
1800                         {
1801                                 union iwreq_data  wrqu;
1802                                 memset(&wrqu, 0, sizeof(wrqu));
1803                                 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1804                                 PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
1805                                 wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1806                         }
1807 #endif
1808
1809                 }
1810                 /* else, ignore it.  TODO: IBSS authentication service
1811                    would be implemented here */
1812         };
1813         return;
1814 }
1815
1816
1817 //2008-8-4 <add> by chester
1818 /*+
1819  *
1820  * Routine Description:
1821  * check if current channel is match ZoneType.
1822  *for USA:1~11;
1823  *      Japan:1~13;
1824  *      Europe:1~13
1825  * Return Value:
1826  *               True:exceed;
1827  *                False:normal case
1828  -*/
1829 static bool
1830 ChannelExceedZoneType(
1831         PSDevice pDevice,
1832         unsigned char byCurrChannel
1833 )
1834 {
1835         bool exceed = false;
1836
1837         switch (pDevice->byZoneType) {
1838         case 0x00:                  //USA:1~11
1839                 if ((byCurrChannel < 1) || (byCurrChannel > 11))
1840                         exceed = true;
1841                 break;
1842         case 0x01:                  //Japan:1~13
1843         case 0x02:                  //Europe:1~13
1844                 if ((byCurrChannel < 1) || (byCurrChannel > 13))
1845                         exceed = true;
1846                 break;
1847         default:                    //reserve for other zonetype
1848                 break;
1849         }
1850
1851         return exceed;
1852 }
1853
1854
1855 /*+
1856  *
1857  * Routine Description:
1858  *   Handles and analysis incoming beacon frames.
1859  *
1860  *
1861  * Return Value:
1862  *    None.
1863  *
1864  -*/
1865
1866 static
1867 void
1868 s_vMgrRxBeacon(
1869         PSDevice pDevice,
1870         PSMgmtObject pMgmt,
1871         PSRxMgmtPacket pRxPacket,
1872         bool bInScan
1873 )
1874 {
1875
1876         PKnownBSS           pBSSList;
1877         WLAN_FR_BEACON      sFrame;
1878         QWORD               qwTSFOffset;
1879         bool bIsBSSIDEqual = false;
1880         bool bIsSSIDEqual = false;
1881         bool bTSFLargeDiff = false;
1882         bool bTSFOffsetPostive = false;
1883         bool bUpdateTSF = false;
1884         bool bIsAPBeacon = false;
1885         bool bIsChannelEqual = false;
1886         unsigned int uLocateByteIndex;
1887         unsigned char byTIMBitOn = 0;
1888         unsigned short wAIDNumber = 0;
1889         unsigned int uNodeIndex;
1890         QWORD               qwTimestamp, qwLocalTSF;
1891         QWORD               qwCurrTSF;
1892         unsigned short wStartIndex = 0;
1893         unsigned short wAIDIndex = 0;
1894         unsigned char byCurrChannel = pRxPacket->byRxChannel;
1895         ERPObject           sERP;
1896         unsigned int uRateLen = WLAN_RATES_MAXLEN;
1897         bool bChannelHit = false;
1898         bool bUpdatePhyParameter = false;
1899         unsigned char byIEChannel = 0;
1900
1901
1902         memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
1903         sFrame.len = pRxPacket->cbMPDULen;
1904         sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1905
1906         // decode the beacon frame
1907         vMgrDecodeBeacon(&sFrame);
1908
1909         if ((sFrame.pwBeaconInterval == 0) ||
1910             (sFrame.pwCapInfo == 0) ||
1911             (sFrame.pSSID == 0) ||
1912             (sFrame.pSuppRates == 0)) {
1913                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
1914                 return;
1915         }
1916
1917
1918         if (sFrame.pDSParms != NULL) {
1919                 if (byCurrChannel > CB_MAX_CHANNEL_24G) {
1920                         // channel remapping to
1921                         byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
1922                 } else {
1923                         byIEChannel = sFrame.pDSParms->byCurrChannel;
1924                 }
1925                 if (byCurrChannel != byIEChannel) {
1926                         // adjust channel info. bcs we rcv adjacent channel packets
1927                         bChannelHit = false;
1928                         byCurrChannel = byIEChannel;
1929                 }
1930         } else {
1931                 // no DS channel info
1932                 bChannelHit = true;
1933         }
1934 //2008-0730-01<Add>by MikeLiu
1935         if (ChannelExceedZoneType(pDevice, byCurrChannel) == true)
1936                 return;
1937
1938         if (sFrame.pERP != NULL) {
1939                 sERP.byERP = sFrame.pERP->byContext;
1940                 sERP.bERPExist = true;
1941
1942         } else {
1943                 sERP.bERPExist = false;
1944                 sERP.byERP = 0;
1945         }
1946
1947         pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
1948         if (pBSSList == NULL) {
1949                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon/insert: RxChannel = : %d\n", byCurrChannel);
1950                 BSSbInsertToBSSList((void *)pDevice,
1951                                     sFrame.pHdr->sA3.abyAddr3,
1952                                     *sFrame.pqwTimestamp,
1953                                     *sFrame.pwBeaconInterval,
1954                                     *sFrame.pwCapInfo,
1955                                     byCurrChannel,
1956                                     sFrame.pSSID,
1957                                     sFrame.pSuppRates,
1958                                     sFrame.pExtSuppRates,
1959                                     &sERP,
1960                                     sFrame.pRSN,
1961                                     sFrame.pRSNWPA,
1962                                     sFrame.pIE_Country,
1963                                     sFrame.pIE_Quiet,
1964                                     sFrame.len - WLAN_HDR_ADDR3_LEN,
1965                                     sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
1966                                     (void *)pRxPacket
1967 );
1968         }
1969         else {
1970 //        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "update bcn: RxChannel = : %d\n", byCurrChannel);
1971                 BSSbUpdateToBSSList((void *)pDevice,
1972                                     *sFrame.pqwTimestamp,
1973                                     *sFrame.pwBeaconInterval,
1974                                     *sFrame.pwCapInfo,
1975                                     byCurrChannel,
1976                                     bChannelHit,
1977                                     sFrame.pSSID,
1978                                     sFrame.pSuppRates,
1979                                     sFrame.pExtSuppRates,
1980                                     &sERP,
1981                                     sFrame.pRSN,
1982                                     sFrame.pRSNWPA,
1983                                     sFrame.pIE_Country,
1984                                     sFrame.pIE_Quiet,
1985                                     pBSSList,
1986                                     sFrame.len - WLAN_HDR_ADDR3_LEN,
1987                                     sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
1988                                     (void *)pRxPacket
1989 );
1990
1991         }
1992
1993         if (bInScan) {
1994                 return;
1995         }
1996
1997         if (byCurrChannel == (unsigned char)pMgmt->uCurrChannel)
1998                 bIsChannelEqual = true;
1999
2000         if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
2001
2002                 // if rx beacon without ERP field
2003                 if (sERP.bERPExist) {
2004                         if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)) {
2005                                 pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
2006                                 pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
2007                         }
2008                 }
2009                 else {
2010                         pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
2011                         pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
2012                 }
2013
2014                 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2015                         if (!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
2016                                 pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
2017                         if (!sERP.bERPExist)
2018                                 pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
2019                 }
2020
2021                 // set to MAC&BBP
2022                 if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
2023                         if (!pDevice->bProtectMode) {
2024                                 MACvEnableProtectMD(pDevice->PortOffset);
2025                                 pDevice->bProtectMode = true;
2026                         }
2027                 }
2028         }
2029
2030
2031         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
2032                 return;
2033
2034         // check if BSSID the same
2035         if (memcmp(sFrame.pHdr->sA3.abyAddr3,
2036                    pMgmt->abyCurrBSSID,
2037                    WLAN_BSSID_LEN) == 0) {
2038
2039                 bIsBSSIDEqual = true;
2040
2041 // 2008-05-21 <add> by Richardtai
2042                 pDevice->uCurrRSSI = pRxPacket->uRSSI;
2043                 pDevice->byCurrSQ = pRxPacket->bySQ;
2044
2045                 if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
2046                         pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2047                         //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
2048                 }
2049         }
2050         // check if SSID the same
2051         if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
2052                 if (memcmp(sFrame.pSSID->abySSID,
2053                            ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
2054                            sFrame.pSSID->len
2055 ) == 0) {
2056                         bIsSSIDEqual = true;
2057                 }
2058         }
2059
2060         if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) == true) &&
2061             (bIsBSSIDEqual == true) &&
2062             (bIsSSIDEqual == true) &&
2063             (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
2064             (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
2065                 // add state check to prevent reconnect fail since we'll receive Beacon
2066
2067                 bIsAPBeacon = true;
2068
2069                 if (pBSSList != NULL) {
2070
2071                         // Compare PHY parameter setting
2072                         if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) {
2073                                 bUpdatePhyParameter = true;
2074                                 pMgmt->wCurrCapInfo = pBSSList->wCapInfo;
2075                         }
2076                         if (sFrame.pERP != NULL) {
2077                                 if ((sFrame.pERP->byElementID == WLAN_EID_ERP) &&
2078                                     (pMgmt->byERPContext != sFrame.pERP->byContext)) {
2079                                         bUpdatePhyParameter = true;
2080                                         pMgmt->byERPContext = sFrame.pERP->byContext;
2081                                 }
2082                         }
2083                         //
2084                         // Basic Rate Set may change dynamically
2085                         //
2086                         if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) {
2087                                 uRateLen = WLAN_RATES_MAXLEN_11B;
2088                         }
2089                         pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
2090                                                                 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2091                                                                 uRateLen);
2092                         pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
2093                                                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
2094                                                                    uRateLen);
2095                         RATEvParseMaxRate((void *)pDevice,
2096                                           (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2097                                           (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
2098                                           true,
2099                                           &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
2100                                           &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
2101                                           &(pMgmt->sNodeDBTable[0].wSuppRate),
2102                                           &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
2103                                           &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
2104                                 );
2105 #ifdef  PLICE_DEBUG
2106                         //printk("RxBeacon:MaxSuppRate is %d\n",pMgmt->sNodeDBTable[0].wMaxSuppRate);
2107 #endif
2108                         if (bUpdatePhyParameter == true) {
2109                                 CARDbSetPhyParameter(pMgmt->pAdapter,
2110                                                      pMgmt->eCurrentPHYMode,
2111                                                      pMgmt->wCurrCapInfo,
2112                                                      pMgmt->byERPContext,
2113                                                      pMgmt->abyCurrSuppRates,
2114                                                      pMgmt->abyCurrExtSuppRates
2115                                         );
2116                         }
2117                         if (sFrame.pIE_PowerConstraint != NULL) {
2118                                 CARDvSetPowerConstraint(pMgmt->pAdapter,
2119                                                         (unsigned char) pBSSList->uChannel,
2120                                                         sFrame.pIE_PowerConstraint->byPower
2121 );
2122                         }
2123                         if (sFrame.pIE_CHSW != NULL) {
2124                                 CARDbChannelSwitch(pMgmt->pAdapter,
2125                                                    sFrame.pIE_CHSW->byMode,
2126                                                    get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode),
2127                                                    sFrame.pIE_CHSW->byCount
2128                                         );
2129
2130                         } else if (bIsChannelEqual == false) {
2131                                 set_channel(pMgmt->pAdapter, pBSSList->uChannel);
2132                         }
2133                 }
2134         }
2135
2136 //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2 \n");
2137         // check if CF field exists
2138         if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
2139                 if (sFrame.pCFParms->wCFPDurRemaining > 0) {
2140                         // TODO: deal with CFP period to set NAV
2141                 }
2142         }
2143
2144         HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
2145         LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
2146         HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF);
2147         LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF);
2148
2149         // check if beacon TSF larger or small than our local TSF
2150         if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
2151                 if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) {
2152                         bTSFOffsetPostive = true;
2153                 }
2154                 else {
2155                         bTSFOffsetPostive = false;
2156                 }
2157         }
2158         else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
2159                 bTSFOffsetPostive = true;
2160         }
2161         else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
2162                 bTSFOffsetPostive = false;
2163         }
2164
2165         if (bTSFOffsetPostive) {
2166                 qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
2167         }
2168         else {
2169                 qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
2170         }
2171
2172         if (HIDWORD(qwTSFOffset) != 0 ||
2173             (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE)) {
2174                 bTSFLargeDiff = true;
2175         }
2176
2177
2178         // if infra mode
2179         if (bIsAPBeacon == true) {
2180
2181                 // Infra mode: Local TSF always follow AP's TSF if Difference huge.
2182                 if (bTSFLargeDiff)
2183                         bUpdateTSF = true;
2184
2185                 if ((pDevice->bEnablePSMode == true) && (sFrame.pTIM != 0)) {
2186
2187                         // deal with DTIM, analysis TIM
2188                         pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false;
2189                         pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
2190                         pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
2191                         wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
2192
2193                         // check if AID in TIM field bit on
2194                         // wStartIndex = N1
2195                         wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
2196                         // AIDIndex = N2
2197                         wAIDIndex = (wAIDNumber >> 3);
2198                         if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
2199                                 uLocateByteIndex = wAIDIndex - wStartIndex;
2200                                 // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
2201                                 if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
2202                                         byTIMBitOn  = (0x01) << ((wAIDNumber) % 8);
2203                                         pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false;
2204                                 }
2205                                 else {
2206                                         pMgmt->bInTIM = false;
2207                                 };
2208                         }
2209                         else {
2210                                 pMgmt->bInTIM = false;
2211                         };
2212
2213                         if (pMgmt->bInTIM ||
2214                             (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
2215                                 pMgmt->bInTIMWake = true;
2216                                 // send out ps-poll packet
2217 //                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
2218                                 if (pMgmt->bInTIM) {
2219                                         PSvSendPSPOLL((PSDevice)pDevice);
2220 //                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
2221                                 }
2222
2223                         }
2224                         else {
2225                                 pMgmt->bInTIMWake = false;
2226                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
2227                                 if (pDevice->bPWBitOn == false) {
2228                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
2229                                         if (PSbSendNullPacket(pDevice))
2230                                                 pDevice->bPWBitOn = true;
2231                                 }
2232                                 if (PSbConsiderPowerDown(pDevice, false, false)) {
2233                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
2234                                 }
2235                         }
2236
2237                 }
2238
2239         }
2240         // if adhoc mode
2241         if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
2242                 if (bIsBSSIDEqual) {
2243                         // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
2244                         if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
2245                                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2246
2247                         // adhoc mode:TSF updated only when beacon larger than local TSF
2248                         if (bTSFLargeDiff && bTSFOffsetPostive &&
2249                             (pMgmt->eCurrState == WMAC_STATE_JOINTED))
2250                                 bUpdateTSF = true;
2251
2252                         // During dpc, already in spinlocked.
2253                         if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
2254
2255                                 // Update the STA, (Technically the Beacons of all the IBSS nodes
2256                                 // should be identical, but that's not happening in practice.
2257                                 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2258                                                                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2259                                                                         WLAN_RATES_MAXLEN_11B);
2260                                 RATEvParseMaxRate((void *)pDevice,
2261                                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2262                                                   NULL,
2263                                                   true,
2264                                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2265                                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2266                                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2267                                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2268                                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2269                                         );
2270                                 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2271                                 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2272                                 pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
2273                         }
2274                         else {
2275                                 // Todo, initial Node content
2276                                 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
2277
2278                                 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2279                                                                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2280                                                                         WLAN_RATES_MAXLEN_11B);
2281                                 RATEvParseMaxRate((void *)pDevice,
2282                                                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2283                                                   NULL,
2284                                                   true,
2285                                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2286                                                   &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2287                                                   &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2288                                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2289                                                   &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2290                                         );
2291
2292                                 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
2293                                 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2294                                 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
2295 #ifdef  PLICE_DEBUG
2296                                 //if (uNodeIndex == 0)
2297                                 {
2298                                         printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex);
2299                                 }
2300 #endif
2301 /*
2302   pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2303   if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
2304   pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
2305 */
2306                         }
2307
2308                         // if other stations joined, indicate connection to upper layer..
2309                         if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
2310                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
2311                                 pMgmt->eCurrState = WMAC_STATE_JOINTED;
2312                                 pDevice->bLinkPass = true;
2313                                 if (netif_queue_stopped(pDevice->dev)) {
2314                                         netif_wake_queue(pDevice->dev);
2315                                 }
2316                                 pMgmt->sNodeDBTable[0].bActive = true;
2317                                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2318
2319                         }
2320                 }
2321                 else if (bIsSSIDEqual) {
2322
2323                         // See other adhoc sta with the same SSID but BSSID is different.
2324                         // adpot this vars only when TSF larger then us.
2325                         if (bTSFLargeDiff && bTSFOffsetPostive) {
2326                                 // we don't support ATIM under adhoc mode
2327                                 // if (sFrame.pIBSSParms->wATIMWindow == 0) {
2328                                 // adpot this vars
2329                                 // TODO: check sFrame cap if privacy on, and support rate syn
2330                                 memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
2331                                 memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
2332                                 pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
2333                                 pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
2334                                 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2335                                                                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2336                                                                         WLAN_RATES_MAXLEN_11B);
2337                                 // set HW beacon interval and re-synchronizing....
2338                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
2339                                 VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod);
2340                                 CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF);
2341                                 CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2342                                 // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
2343                                 MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
2344
2345                                 CARDbSetPhyParameter(pMgmt->pAdapter,
2346                                                      pMgmt->eCurrentPHYMode,
2347                                                      pMgmt->wCurrCapInfo,
2348                                                      pMgmt->byERPContext,
2349                                                      pMgmt->abyCurrSuppRates,
2350                                                      pMgmt->abyCurrExtSuppRates);
2351
2352
2353                                 // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
2354                                 // set highest basic rate
2355                                 // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates);
2356                                 // Prepare beacon frame
2357                                 bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
2358                                 //  }
2359                         }
2360                 }
2361         }
2362         // endian issue ???
2363         // Update TSF
2364         if (bUpdateTSF) {
2365                 CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2366                 CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
2367                 CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2368                 CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2369         }
2370
2371         return;
2372 }
2373
2374
2375
2376 /*+
2377  *
2378  * Routine Description:
2379  *   Instructs the hw to create a bss using the supplied
2380  *   attributes. Note that this implementation only supports Ad-Hoc
2381  *   BSS creation.
2382  *
2383  *
2384  * Return Value:
2385  *    CMD_STATUS
2386  *
2387  -*/
2388 void
2389 vMgrCreateOwnIBSS(
2390         void *hDeviceContext,
2391         PCMD_STATUS pStatus
2392 )
2393 {
2394         PSDevice            pDevice = (PSDevice)hDeviceContext;
2395         PSMgmtObject        pMgmt = pDevice->pMgmt;
2396         unsigned short wMaxBasicRate;
2397         unsigned short wMaxSuppRate;
2398         unsigned char byTopCCKBasicRate;
2399         unsigned char byTopOFDMBasicRate;
2400         QWORD               qwCurrTSF;
2401         unsigned int ii;
2402         unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
2403         unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
2404         unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2405         unsigned short wSuppRate;
2406
2407         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
2408
2409         if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2410                 if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
2411                     (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
2412                     (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
2413                         // encryption mode error
2414                         *pStatus = CMD_STATUS_FAILURE;
2415                         return;
2416                 }
2417         }
2418
2419         pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2420         pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
2421
2422         if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2423                 pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
2424         } else {
2425                 if (pDevice->byBBType == BB_TYPE_11G)
2426                         pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
2427                 if (pDevice->byBBType == BB_TYPE_11B)
2428                         pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
2429                 if (pDevice->byBBType == BB_TYPE_11A)
2430                         pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
2431         }
2432
2433         if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
2434                 pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
2435                 pMgmt->abyCurrExtSuppRates[1] = 0;
2436                 for (ii = 0; ii < 4; ii++)
2437                         pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2438         } else {
2439                 pMgmt->abyCurrSuppRates[1] = 8;
2440                 pMgmt->abyCurrExtSuppRates[1] = 0;
2441                 for (ii = 0; ii < 8; ii++)
2442                         pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2443         }
2444
2445
2446         if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
2447                 pMgmt->abyCurrSuppRates[1] = 8;
2448                 pMgmt->abyCurrExtSuppRates[1] = 4;
2449                 for (ii = 0; ii < 4; ii++)
2450                         pMgmt->abyCurrSuppRates[2+ii] =  abyCCK_RATE[ii];
2451                 for (ii = 4; ii < 8; ii++)
2452                         pMgmt->abyCurrSuppRates[2+ii] =  abyOFDM_RATE[ii-4];
2453                 for (ii = 0; ii < 4; ii++)
2454                         pMgmt->abyCurrExtSuppRates[2+ii] =  abyOFDM_RATE[ii+4];
2455         }
2456
2457
2458         // Disable Protect Mode
2459         pDevice->bProtectMode = 0;
2460         MACvDisableProtectMD(pDevice->PortOffset);
2461
2462         pDevice->bBarkerPreambleMd = 0;
2463         MACvDisableBarkerPreambleMd(pDevice->PortOffset);
2464
2465         // Kyle Test 2003.11.04
2466
2467         // set HW beacon interval
2468         if (pMgmt->wIBSSBeaconPeriod == 0)
2469                 pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
2470
2471
2472         CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2473         // clear TSF counter
2474         VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
2475         // enable TSF counter
2476         VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
2477
2478         // set Next TBTT
2479         CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod);
2480
2481         pMgmt->uIBSSChannel = pDevice->uChannel;
2482
2483         if (pMgmt->uIBSSChannel == 0)
2484                 pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
2485
2486
2487         // set basic rate
2488
2489         RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2490                           (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true,
2491                           &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2492                           &byTopCCKBasicRate, &byTopOFDMBasicRate);
2493
2494
2495         if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2496                 pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
2497         }
2498
2499         if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2500                 memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6);
2501                 pMgmt->byIBSSDFSRecovery = 10;
2502                 pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2503         }
2504
2505         // Adopt pre-configured IBSS vars to current vars
2506         pMgmt->eCurrState = WMAC_STATE_STARTED;
2507         pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
2508         pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2509         pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
2510         MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
2511         pDevice->uCurrRSSI = 0;
2512         pDevice->byCurrSQ = 0;
2513         //memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
2514         // ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
2515         memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2516         memcpy(pMgmt->abyCurrSSID,
2517                pMgmt->abyDesireSSID,
2518                ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
2519 );
2520
2521         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2522                 // AP mode BSSID = MAC addr
2523                 memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
2524                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "AP beacon created BSSID:%pM\n",
2525                         pMgmt->abyCurrBSSID);
2526         }
2527
2528         if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2529
2530                 // BSSID selected must be randomized as spec 11.1.3
2531                 pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF) & 0x000000ff);
2532                 pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0000ff00) >> 8);
2533                 pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00ff0000) >> 16);
2534                 pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00000ff0) >> 4);
2535                 pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF) & 0x000ff000) >> 12);
2536                 pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0ff00000) >> 20);
2537                 pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
2538                 pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
2539                 pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
2540                 pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
2541                 pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
2542                 pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
2543                 pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
2544                 pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
2545
2546
2547                 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Adhoc beacon created bssid:%pM\n",
2548                         pMgmt->abyCurrBSSID);
2549         }
2550
2551         // Set Capability Info
2552         pMgmt->wCurrCapInfo = 0;
2553
2554         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2555                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
2556                 pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
2557                 pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2558         }
2559
2560         if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2561                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
2562         }
2563
2564         if (pDevice->bEncryptionEnable) {
2565                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
2566                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2567                         if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2568                                 pMgmt->byCSSPK = KEY_CTL_CCMP;
2569                                 pMgmt->byCSSGK = KEY_CTL_CCMP;
2570                         } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2571                                 pMgmt->byCSSPK = KEY_CTL_TKIP;
2572                                 pMgmt->byCSSGK = KEY_CTL_TKIP;
2573                         } else {
2574                                 pMgmt->byCSSPK = KEY_CTL_NONE;
2575                                 pMgmt->byCSSGK = KEY_CTL_WEP;
2576                         }
2577                 } else {
2578                         pMgmt->byCSSPK = KEY_CTL_WEP;
2579                         pMgmt->byCSSGK = KEY_CTL_WEP;
2580                 }
2581         }
2582
2583         pMgmt->byERPContext = 0;
2584
2585 //    memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
2586
2587         if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2588                 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP);
2589         } else {
2590                 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
2591         }
2592
2593         CARDbSetPhyParameter(pMgmt->pAdapter,
2594                              pMgmt->eCurrentPHYMode,
2595                              pMgmt->wCurrCapInfo,
2596                              pMgmt->byERPContext,
2597                              pMgmt->abyCurrSuppRates,
2598                              pMgmt->abyCurrExtSuppRates
2599                 );
2600
2601         CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod);
2602         // set channel and clear NAV
2603         set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel);
2604         pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2605
2606         if (CARDbIsShortPreamble(pMgmt->pAdapter)) {
2607                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
2608         } else {
2609                 pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
2610         }
2611
2612         if ((pMgmt->b11hEnable == true) &&
2613             (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
2614                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
2615         } else {
2616                 pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1));
2617         }
2618
2619         pMgmt->eCurrState = WMAC_STATE_STARTED;
2620         // Prepare beacon to send
2621         if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt)) {
2622                 *pStatus = CMD_STATUS_SUCCESS;
2623         }
2624
2625         return;
2626 }
2627
2628
2629
2630 /*+
2631  *
2632  * Routine Description:
2633  *   Instructs wmac to join a bss using the supplied attributes.
2634  *   The arguments may the BSSID or SSID and the rest of the
2635  *   attributes are obtained from the scan result of known bss list.
2636  *
2637  *
2638  * Return Value:
2639  *    None.
2640  *
2641  -*/
2642
2643 void
2644 vMgrJoinBSSBegin(
2645         void *hDeviceContext,
2646         PCMD_STATUS pStatus
2647 )
2648 {
2649
2650         PSDevice     pDevice = (PSDevice)hDeviceContext;
2651         PSMgmtObject    pMgmt = pDevice->pMgmt;
2652         PKnownBSS       pCurr = NULL;
2653         unsigned int ii, uu;
2654         PWLAN_IE_SUPP_RATES pItemRates = NULL;
2655         PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
2656         PWLAN_IE_SSID   pItemSSID;
2657         unsigned int uRateLen = WLAN_RATES_MAXLEN;
2658         unsigned short wMaxBasicRate = RATE_1M;
2659         unsigned short wMaxSuppRate = RATE_1M;
2660         unsigned short wSuppRate;
2661         unsigned char byTopCCKBasicRate = RATE_1M;
2662         unsigned char byTopOFDMBasicRate = RATE_1M;
2663
2664
2665         for (ii = 0; ii < MAX_BSS_NUM; ii++) {
2666                 if (pMgmt->sBSSList[ii].bActive == true)
2667                         break;
2668         }
2669
2670         if (ii == MAX_BSS_NUM) {
2671                 *pStatus = CMD_STATUS_RESOURCES;
2672                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
2673                 return;
2674         }
2675
2676         // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
2677         // Search known BSS list for prefer BSSID or SSID
2678
2679         pCurr = BSSpSearchBSSList(pDevice,
2680                                   pMgmt->abyDesireBSSID,
2681                                   pMgmt->abyDesireSSID,
2682                                   pMgmt->eConfigPHYMode
2683 );
2684
2685         if (pCurr == NULL) {
2686                 *pStatus = CMD_STATUS_RESOURCES;
2687                 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
2688                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
2689                 return;
2690         }
2691
2692         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
2693         if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))) {
2694
2695                 if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
2696
2697                         // patch for CISCO migration mode
2698 /*
2699   if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2700   if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
2701   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
2702   // encryption mode error
2703   pMgmt->eCurrState = WMAC_STATE_IDLE;
2704   return;
2705   }
2706   } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2707   if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
2708   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
2709   // encryption mode error
2710   pMgmt->eCurrState = WMAC_STATE_IDLE;
2711   return;
2712   }
2713   }
2714 */
2715                 }
2716
2717 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2718                 //if (pDevice->bWPASuppWextEnabled == true)
2719                 Encyption_Rebuild(pDevice, pCurr);
2720 #endif
2721                 // Infrastructure BSS
2722                 s_vMgrSynchBSS(pDevice,
2723                                WMAC_MODE_ESS_STA,
2724                                pCurr,
2725                                pStatus
2726 );
2727
2728                 if (*pStatus == CMD_STATUS_SUCCESS) {
2729
2730                         // Adopt this BSS state vars in Mgmt Object
2731                         pMgmt->uCurrChannel = pCurr->uChannel;
2732
2733                         memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2734                         memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2735
2736                         if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
2737                                 uRateLen = WLAN_RATES_MAXLEN_11B;
2738                         }
2739
2740                         pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
2741                         pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
2742
2743                         // Parse Support Rate IE
2744                         pItemRates->byElementID = WLAN_EID_SUPP_RATES;
2745                         pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2746                                                      pItemRates,
2747                                                      uRateLen);
2748
2749                         // Parse Extension Support Rate IE
2750                         pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
2751                         pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
2752                                                         pItemExtRates,
2753                                                         uRateLen);
2754                         // Stuffing Rate IE
2755                         if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
2756                                 for (ii = 0; ii < (unsigned int)(8 - pItemRates->len);) {
2757                                         pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii];
2758                                         ii++;
2759                                         if (pItemExtRates->len <= ii)
2760                                                 break;
2761                                 }
2762                                 pItemRates->len += (unsigned char)ii;
2763                                 if (pItemExtRates->len - ii > 0) {
2764                                         pItemExtRates->len -= (unsigned char)ii;
2765                                         for (uu = 0; uu < pItemExtRates->len; uu++) {
2766                                                 pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
2767                                         }
2768                                 } else {
2769                                         pItemExtRates->len = 0;
2770                                 }
2771                         }
2772
2773                         RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true,
2774                                           &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2775                                           &byTopCCKBasicRate, &byTopOFDMBasicRate);
2776
2777                         // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
2778                         // TODO: deal with if wCapInfo the PS-Pollable is on.
2779                         pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2780                         memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2781                         memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2782                         memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2783
2784                         pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
2785
2786                         pMgmt->eCurrState = WMAC_STATE_JOINTED;
2787                         // Adopt BSS state in Adapter Device Object
2788                         //pDevice->byOpMode = OP_MODE_INFRASTRUCTURE;
2789 //            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2790
2791                         // Add current BSS to Candidate list
2792                         // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
2793                         if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
2794                                 bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
2795                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult);
2796                                 if (bResult == false) {
2797                                         vFlush_PMKID_Candidate((void *)pDevice);
2798                                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n");
2799                                         bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
2800                                 }
2801                         }
2802
2803                         // Preamble type auto-switch: if AP can receive short-preamble cap,
2804                         // we can turn on too.
2805
2806                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join ESS\n");
2807
2808
2809
2810                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n");
2811                 }
2812                 else {
2813                         pMgmt->eCurrState = WMAC_STATE_IDLE;
2814                 };
2815
2816
2817         }
2818         else {
2819                 // ad-hoc mode BSS
2820                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2821
2822                         if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2823                                 if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == false) {
2824                                         // encryption mode error
2825                                         pMgmt->eCurrState = WMAC_STATE_IDLE;
2826                                         return;
2827                                 }
2828                         } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2829                                 if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == false) {
2830                                         // encryption mode error
2831                                         pMgmt->eCurrState = WMAC_STATE_IDLE;
2832                                         return;
2833                                 }
2834                         } else {
2835                                 // encryption mode error
2836                                 pMgmt->eCurrState = WMAC_STATE_IDLE;
2837                                 return;
2838                         }
2839                 }
2840
2841                 s_vMgrSynchBSS(pDevice,
2842                                WMAC_MODE_IBSS_STA,
2843                                pCurr,
2844                                pStatus
2845 );
2846
2847                 if (*pStatus == CMD_STATUS_SUCCESS) {
2848                         // Adopt this BSS state vars in Mgmt Object
2849                         // TODO: check if CapInfo privacy on, but we don't..
2850                         pMgmt->uCurrChannel = pCurr->uChannel;
2851
2852
2853                         // Parse Support Rate IE
2854                         pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2855                         pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2856                                                                 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2857                                                                 WLAN_RATES_MAXLEN_11B);
2858                         // set basic rate
2859                         RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2860                                           NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2861                                           &byTopCCKBasicRate, &byTopOFDMBasicRate);
2862
2863                         pMgmt->wCurrCapInfo = pCurr->wCapInfo;
2864                         pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2865                         memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2866                         memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2867                         memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2868 //          pMgmt->wCurrATIMWindow = pCurr->wATIMWindow;
2869                         MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
2870                         pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2871
2872                         pMgmt->eCurrState = WMAC_STATE_STARTED;
2873                         // Adopt BSS state in Adapter Device Object
2874                         //pDevice->byOpMode = OP_MODE_ADHOC;
2875 //            pDevice->bLinkPass = true;
2876 //            memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2877
2878                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join IBSS ok:%pM\n",
2879                                 pMgmt->abyCurrBSSID);
2880                         // Preamble type auto-switch: if AP can receive short-preamble cap,
2881                         // and if registry setting is short preamble we can turn on too.
2882
2883                         // Prepare beacon
2884                         bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
2885                 }
2886                 else {
2887                         pMgmt->eCurrState = WMAC_STATE_IDLE;
2888                 };
2889         };
2890         return;
2891 }
2892
2893
2894
2895 /*+
2896  *
2897  * Routine Description:
2898  * Set HW to synchronize a specific BSS from known BSS list.
2899  *
2900  *
2901  * Return Value:
2902  *    PCM_STATUS
2903  *
2904  -*/
2905 static
2906 void
2907 s_vMgrSynchBSS(
2908         PSDevice      pDevice,
2909         unsigned int uBSSMode,
2910         PKnownBSS     pCurr,
2911         PCMD_STATUS  pStatus
2912 )
2913 {
2914         CARD_PHY_TYPE   ePhyType = PHY_TYPE_11B;
2915         PSMgmtObject  pMgmt = pDevice->pMgmt;
2916 //    int     ii;
2917         //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
2918         unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
2919         unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
2920         //6M,   9M,   12M,  48M
2921         unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2922         unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
2923
2924
2925         *pStatus = CMD_STATUS_FAILURE;
2926
2927         if (s_bCipherMatch(pCurr,
2928                            pDevice->eEncryptionStatus,
2929                            &(pMgmt->byCSSPK),
2930                            &(pMgmt->byCSSGK)) == false) {
2931                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
2932                 return;
2933         }
2934
2935         pMgmt->pCurrBSS = pCurr;
2936
2937         // if previous mode is IBSS.
2938         if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2939                 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY);
2940                 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
2941         }
2942
2943         // Init the BSS informations
2944         pDevice->bCCK = true;
2945         pDevice->bProtectMode = false;
2946         MACvDisableProtectMD(pDevice->PortOffset);
2947         pDevice->bBarkerPreambleMd = false;
2948         MACvDisableBarkerPreambleMd(pDevice->PortOffset);
2949         pDevice->bNonERPPresent = false;
2950         pDevice->byPreambleType = 0;
2951         pDevice->wBasicRate = 0;
2952         // Set Basic Rate
2953         CARDbAddBasicRate((void *)pDevice, RATE_1M);
2954         // calculate TSF offset
2955         // TSF Offset = Received Timestamp TSF - Marked Local's TSF
2956         CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
2957
2958         CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval);
2959
2960         // set Next TBTT
2961         // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval
2962         CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval);
2963
2964         // set BSSID
2965         MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID);
2966
2967         MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
2968
2969         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = "
2970                 "%pM\n", pMgmt->abyCurrBSSID);
2971
2972         if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
2973                 if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) ||
2974                     (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2975                         ePhyType = PHY_TYPE_11A;
2976                 } else {
2977                         return;
2978                 }
2979         } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
2980                 if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) ||
2981                     (pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
2982                     (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2983                         ePhyType = PHY_TYPE_11B;
2984                 } else {
2985                         return;
2986                 }
2987         } else {
2988                 if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
2989                     (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2990                         ePhyType = PHY_TYPE_11G;
2991                 } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) {
2992                         ePhyType = PHY_TYPE_11B;
2993                 } else {
2994                         return;
2995                 }
2996         }
2997
2998         if (ePhyType == PHY_TYPE_11A) {
2999                 memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
3000                 pMgmt->abyCurrExtSuppRates[1] = 0;
3001         } else if (ePhyType == PHY_TYPE_11B) {
3002                 memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
3003                 pMgmt->abyCurrExtSuppRates[1] = 0;
3004         } else {
3005                 memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
3006                 memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
3007         }
3008
3009
3010         if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) {
3011                 CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_INFRASTRUCTURE);
3012                 // Add current BSS to Candidate list
3013                 // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
3014                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
3015                         CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap);
3016                 }
3017         } else {
3018                 CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC);
3019         }
3020
3021         if (CARDbSetPhyParameter(pMgmt->pAdapter,
3022                                  ePhyType,
3023                                  pCurr->wCapInfo,
3024                                  pCurr->sERP.byERP,
3025                                  pMgmt->abyCurrSuppRates,
3026                                  pMgmt->abyCurrExtSuppRates
3027                     ) != true) {
3028                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
3029                 return;
3030         }
3031         // set channel and clear NAV
3032         if (set_channel(pMgmt->pAdapter, pCurr->uChannel) == false) {
3033                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
3034                 return;
3035         }
3036
3037 /*
3038   for (ii=0; ii<BB_VGA_LEVEL; ii++) {
3039   if (pCurr->ldBmMAX< pDevice->ldBmThreshold[ii]) {
3040   pDevice->byBBVGANew = pDevice->abyBBVGA[ii];
3041   break;
3042   }
3043   }
3044
3045   if (pDevice->byBBVGANew != pDevice->byBBVGACurrent) {
3046   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] \n",
3047   (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
3048   printk("RSSI[%d] NewGain[%d] OldGain[%d] \n",
3049   (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
3050   BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew);
3051   }
3052   printk("ldBmMAX[%d] NewGain[%d] OldGain[%d] \n",
3053   (int)pCurr->ldBmMAX, pDevice->byBBVGANew, pDevice->byBBVGACurrent);
3054 */
3055         pMgmt->uCurrChannel = pCurr->uChannel;
3056         pMgmt->eCurrentPHYMode = ePhyType;
3057         pMgmt->byERPContext = pCurr->sERP.byERP;
3058         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel);
3059
3060
3061         *pStatus = CMD_STATUS_SUCCESS;
3062
3063
3064         return;
3065 };
3066
3067 //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption
3068 //                   ,need reset eAuthenMode and eEncryptionStatus
3069 static void  Encyption_Rebuild(
3070         PSDevice pDevice,
3071         PKnownBSS pCurr
3072 )
3073 {
3074         PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
3075         // unsigned int ii , uSameBssidNum=0;
3076
3077         //  for (ii = 0; ii < MAX_BSS_NUM; ii++) {
3078         //   if (pMgmt->sBSSList[ii].bActive &&
3079         //      !compare_ether_addr(pMgmt->sBSSList[ii].abyBSSID, pCurr->abyBSSID)) {
3080         //       uSameBssidNum++;
3081         //   }
3082         // }
3083         //   if (uSameBssidNum>=2) {     //we only check AP in hidden sssid  mode
3084         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selection,
3085             (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-select it according to real pairwise-key info.
3086                 if (pCurr->bWPAValid == true)  {   //WPA-PSK
3087                         pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
3088                         if (pCurr->abyPKType[0] == WPA_TKIP) {
3089                                 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
3090                                 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
3091                         }
3092                         else if (pCurr->abyPKType[0] == WPA_AESCCMP) {
3093                                 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
3094                                 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
3095                         }
3096                 }
3097                 else if (pCurr->bWPA2Valid == true) {  //WPA2-PSK
3098                         pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
3099                         if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
3100                                 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
3101                                 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
3102                         }
3103                         else if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
3104                                 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
3105                                 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
3106                         }
3107                 }
3108         }
3109         //  }
3110         return;
3111 }
3112
3113
3114 /*+
3115  *
3116  * Routine Description:
3117  *  Format TIM field
3118  *
3119  *
3120  * Return Value:
3121  *    void
3122  *
3123  -*/
3124
3125 static
3126 void
3127 s_vMgrFormatTIM(
3128         PSMgmtObject pMgmt,
3129         PWLAN_IE_TIM pTIM
3130 )
3131 {
3132         unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
3133         unsigned char byMap;
3134         unsigned int ii, jj;
3135         bool bStartFound = false;
3136         bool bMulticast = false;
3137         unsigned short wStartIndex = 0;
3138         unsigned short wEndIndex = 0;
3139
3140
3141         // Find size of partial virtual bitmap
3142         for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
3143                 byMap = pMgmt->abyPSTxMap[ii];
3144                 if (!ii) {
3145                         // Mask out the broadcast bit which is indicated separately.
3146                         bMulticast = (byMap & byMask[0]) != 0;
3147                         if (bMulticast) {
3148                                 pMgmt->sNodeDBTable[0].bRxPSPoll = true;
3149                         }
3150                         byMap = 0;
3151                 }
3152                 if (byMap) {
3153                         if (!bStartFound) {
3154                                 bStartFound = true;
3155                                 wStartIndex = ii;
3156                         }
3157                         wEndIndex = ii;
3158                 }
3159         }
3160
3161
3162         // Round start index down to nearest even number
3163         wStartIndex &=  ~BIT0;
3164
3165         // Round end index up to nearest even number
3166         wEndIndex = ((wEndIndex + 1) & ~BIT0);
3167
3168         // Size of element payload
3169
3170         pTIM->len =  3 + (wEndIndex - wStartIndex) + 1;
3171
3172         // Fill in the Fixed parts of the TIM
3173         pTIM->byDTIMCount = pMgmt->byDTIMCount;
3174         pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
3175         pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
3176                 (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
3177
3178         // Append variable part of TIM
3179
3180         for (ii = wStartIndex, jj = 0; ii <= wEndIndex; ii++, jj++) {
3181                 pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
3182         }
3183
3184         // Aid = 0 don't used.
3185         pTIM->byVirtBitMap[0]  &= ~BIT0;
3186 }
3187
3188
3189 /*+
3190  *
3191  * Routine Description:
3192  *  Constructs an Beacon frame(Ad-hoc mode)
3193  *
3194  *
3195  * Return Value:
3196  *    PTR to frame; or NULL on allocation failure
3197  *
3198  -*/
3199
3200 static
3201 PSTxMgmtPacket
3202 s_MgrMakeBeacon(
3203         PSDevice pDevice,
3204         PSMgmtObject pMgmt,
3205         unsigned short wCurrCapInfo,
3206         unsigned short wCurrBeaconPeriod,
3207         unsigned int uCurrChannel,
3208         unsigned short wCurrATIMWinodw,
3209         PWLAN_IE_SSID pCurrSSID,
3210         unsigned char *pCurrBSSID,
3211         PWLAN_IE_SUPP_RATES pCurrSuppRates,
3212         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3213 )
3214 {
3215         PSTxMgmtPacket      pTxPacket = NULL;
3216         WLAN_FR_BEACON      sFrame;
3217         unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3218         unsigned char *pbyBuffer;
3219         unsigned int uLength = 0;
3220         PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
3221         unsigned int ii;
3222
3223         // prepare beacon frame
3224         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3225         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
3226         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3227         // Setup the sFrame structure.
3228         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3229         sFrame.len = WLAN_BEACON_FR_MAXLEN;
3230         vMgrEncodeBeacon(&sFrame);
3231         // Setup the header
3232         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3233                 (
3234                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3235                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
3236 ));
3237
3238         if (pDevice->bEnablePSMode) {
3239                 sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1));
3240         }
3241
3242         memcpy(sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
3243         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3244         memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3245         *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3246         *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3247         // Copy SSID
3248         sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3249         sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3250         memcpy(sFrame.pSSID,
3251                pCurrSSID,
3252                ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3253 );
3254         // Copy the rate set
3255         sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3256         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3257         memcpy(sFrame.pSuppRates,
3258                pCurrSuppRates,
3259                ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3260 );
3261         // DS parameter
3262         if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
3263                 sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3264                 sFrame.len += (1) + WLAN_IEHDR_LEN;
3265                 sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3266                 sFrame.pDSParms->len = 1;
3267                 sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
3268         }
3269         // TIM field
3270         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
3271                 sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
3272                 sFrame.pTIM->byElementID = WLAN_EID_TIM;
3273                 s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
3274                 sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
3275         }
3276
3277         if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3278
3279                 // IBSS parameter
3280                 sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3281                 sFrame.len += (2) + WLAN_IEHDR_LEN;
3282                 sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3283                 sFrame.pIBSSParms->len = 2;
3284                 sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
3285                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3286                         /* RSN parameter */
3287                         sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3288                         sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3289                         sFrame.pRSNWPA->len = 12;
3290                         sFrame.pRSNWPA->abyOUI[0] = 0x00;
3291                         sFrame.pRSNWPA->abyOUI[1] = 0x50;
3292                         sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3293                         sFrame.pRSNWPA->abyOUI[3] = 0x01;
3294                         sFrame.pRSNWPA->wVersion = 1;
3295                         sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3296                         sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3297                         sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3298                         if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
3299                                 sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
3300                         else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
3301                                 sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
3302                         else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
3303                                 sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
3304                         else
3305                                 sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
3306
3307                         // Pairwise Key Cipher Suite
3308                         sFrame.pRSNWPA->wPKCount = 0;
3309                         // Auth Key Management Suite
3310                         *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0;
3311                         sFrame.pRSNWPA->len += 2;
3312
3313                         // RSN Capabilities
3314                         *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0;
3315                         sFrame.pRSNWPA->len += 2;
3316                         sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3317                 }
3318         }
3319
3320         if ((pMgmt->b11hEnable == true) &&
3321             (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
3322                 // Country IE
3323                 pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
3324                 set_country_IE(pMgmt->pAdapter, pbyBuffer);
3325                 set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
3326                 uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
3327                 pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
3328                 // Power Constrain IE
3329                 ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
3330                 ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
3331                 ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
3332                 pbyBuffer += (1) + WLAN_IEHDR_LEN;
3333                 uLength += (1) + WLAN_IEHDR_LEN;
3334                 if (pMgmt->bSwitchChannel == true) {
3335                         // Channel Switch IE
3336                         ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
3337                         ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
3338                         ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
3339                         ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
3340                         ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
3341                         pbyBuffer += (3) + WLAN_IEHDR_LEN;
3342                         uLength += (3) + WLAN_IEHDR_LEN;
3343                 }
3344                 // TPC report
3345                 ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
3346                 ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
3347                 ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
3348                 ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
3349                 pbyBuffer += (2) + WLAN_IEHDR_LEN;
3350                 uLength += (2) + WLAN_IEHDR_LEN;
3351                 // IBSS DFS
3352                 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3353                         pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
3354                         pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
3355                         pIBSSDFS->len = 7;
3356                         memcpy(pIBSSDFS->abyDFSOwner,
3357                                pMgmt->abyIBSSDFSOwner,
3358                                6);
3359                         pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
3360                         pbyBuffer += (7) + WLAN_IEHDR_LEN;
3361                         uLength += (7) + WLAN_IEHDR_LEN;
3362                         for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) {
3363                                 if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) {
3364                                         pbyBuffer += 2;
3365                                         uLength += 2;
3366                                         pIBSSDFS->len += 2;
3367                                 }
3368                         }
3369                 }
3370                 sFrame.len += uLength;
3371         }
3372
3373         if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
3374                 sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3375                 sFrame.len += 1 + WLAN_IEHDR_LEN;
3376                 sFrame.pERP->byElementID = WLAN_EID_ERP;
3377                 sFrame.pERP->len = 1;
3378                 sFrame.pERP->byContext = 0;
3379                 if (pDevice->bProtectMode == true)
3380                         sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3381                 if (pDevice->bNonERPPresent == true)
3382                         sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3383                 if (pDevice->bBarkerPreambleMd == true)
3384                         sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3385         }
3386         if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3387                 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3388                 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3389                 memcpy(sFrame.pExtSuppRates,
3390                        pCurrExtSuppRates,
3391                        ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3392 );
3393         }
3394         // hostapd wpa/wpa2 IE
3395         if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) {
3396                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3397                         if (pMgmt->wWPAIELen != 0) {
3398                                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3399                                 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3400                                 sFrame.len += pMgmt->wWPAIELen;
3401                         }
3402                 }
3403         }
3404
3405         /* Adjust the length fields */
3406         pTxPacket->cbMPDULen = sFrame.len;
3407         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3408
3409         return pTxPacket;
3410 }
3411
3412
3413
3414
3415
3416 /*+
3417  *
3418  * Routine Description:
3419  *  Constructs an Prob-response frame
3420  *
3421  *
3422  * Return Value:
3423  *    PTR to frame; or NULL on allocation failure
3424  *
3425  -*/
3426
3427
3428
3429
3430 PSTxMgmtPacket
3431 s_MgrMakeProbeResponse(
3432         PSDevice pDevice,
3433         PSMgmtObject pMgmt,
3434         unsigned short wCurrCapInfo,
3435         unsigned short wCurrBeaconPeriod,
3436         unsigned int uCurrChannel,
3437         unsigned short wCurrATIMWinodw,
3438         unsigned char *pDstAddr,
3439         PWLAN_IE_SSID pCurrSSID,
3440         unsigned char *pCurrBSSID,
3441         PWLAN_IE_SUPP_RATES pCurrSuppRates,
3442         PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
3443         unsigned char byPHYType
3444 )
3445 {
3446         PSTxMgmtPacket      pTxPacket = NULL;
3447         WLAN_FR_PROBERESP   sFrame;
3448         unsigned char *pbyBuffer;
3449         unsigned int uLength = 0;
3450         PWLAN_IE_IBSS_DFS   pIBSSDFS = NULL;
3451         unsigned int ii;
3452
3453
3454         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3455         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
3456         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3457         // Setup the sFrame structure.
3458         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3459         sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
3460         vMgrEncodeProbeResponse(&sFrame);
3461         // Setup the header
3462         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3463                 (
3464                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3465                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
3466 ));
3467         memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3468         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3469         memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3470         *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3471         *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3472
3473         if (byPHYType == BB_TYPE_11B) {
3474                 *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
3475         }
3476
3477         // Copy SSID
3478         sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3479         sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3480         memcpy(sFrame.pSSID,
3481                pCurrSSID,
3482                ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3483 );
3484         // Copy the rate set
3485         sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3486
3487         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3488         memcpy(sFrame.pSuppRates,
3489                pCurrSuppRates,
3490                ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3491 );
3492
3493         // DS parameter
3494         if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
3495                 sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3496                 sFrame.len += (1) + WLAN_IEHDR_LEN;
3497                 sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3498                 sFrame.pDSParms->len = 1;
3499                 sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
3500         }
3501
3502         if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3503                 // IBSS parameter
3504                 sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3505                 sFrame.len += (2) + WLAN_IEHDR_LEN;
3506                 sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3507                 sFrame.pIBSSParms->len = 2;
3508                 sFrame.pIBSSParms->wATIMWindow = 0;
3509         }
3510         if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
3511                 sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3512                 sFrame.len += 1 + WLAN_IEHDR_LEN;
3513                 sFrame.pERP->byElementID = WLAN_EID_ERP;
3514                 sFrame.pERP->len = 1;
3515                 sFrame.pERP->byContext = 0;
3516                 if (pDevice->bProtectMode == true)
3517                         sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3518                 if (pDevice->bNonERPPresent == true)
3519                         sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3520                 if (pDevice->bBarkerPreambleMd == true)
3521                         sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3522         }
3523
3524         if ((pMgmt->b11hEnable == true) &&
3525             (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
3526                 // Country IE
3527                 pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
3528                 set_country_IE(pMgmt->pAdapter, pbyBuffer);
3529                 set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
3530                 uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
3531                 pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
3532                 // Power Constrain IE
3533                 ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
3534                 ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
3535                 ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
3536                 pbyBuffer += (1) + WLAN_IEHDR_LEN;
3537                 uLength += (1) + WLAN_IEHDR_LEN;
3538                 if (pMgmt->bSwitchChannel == true) {
3539                         // Channel Switch IE
3540                         ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
3541                         ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
3542                         ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
3543                         ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
3544                         ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
3545                         pbyBuffer += (3) + WLAN_IEHDR_LEN;
3546                         uLength += (3) + WLAN_IEHDR_LEN;
3547                 }
3548                 // TPC report
3549                 ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
3550                 ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
3551                 ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
3552                 ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
3553                 pbyBuffer += (2) + WLAN_IEHDR_LEN;
3554                 uLength += (2) + WLAN_IEHDR_LEN;
3555                 // IBSS DFS
3556                 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3557                         pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
3558                         pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
3559                         pIBSSDFS->len = 7;
3560                         memcpy(pIBSSDFS->abyDFSOwner,
3561                                pMgmt->abyIBSSDFSOwner,
3562                                6);
3563                         pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
3564                         pbyBuffer += (7) + WLAN_IEHDR_LEN;
3565                         uLength += (7) + WLAN_IEHDR_LEN;
3566                         for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) {
3567                                 if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1) == true) {
3568                                         pbyBuffer += 2;
3569                                         uLength += 2;
3570                                         pIBSSDFS->len += 2;
3571                                 }
3572                         }
3573                 }
3574                 sFrame.len += uLength;
3575         }
3576
3577
3578         if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3579                 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3580                 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3581                 memcpy(sFrame.pExtSuppRates,
3582                        pCurrExtSuppRates,
3583                        ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3584 );
3585         }
3586
3587         // hostapd wpa/wpa2 IE
3588         if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == true)) {
3589                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3590                         if (pMgmt->wWPAIELen != 0) {
3591                                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3592                                 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3593                                 sFrame.len += pMgmt->wWPAIELen;
3594                         }
3595                 }
3596         }
3597
3598         // Adjust the length fields
3599         pTxPacket->cbMPDULen = sFrame.len;
3600         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3601
3602         return pTxPacket;
3603 }
3604
3605
3606
3607 /*+
3608  *
3609  * Routine Description:
3610  *  Constructs an association request frame
3611  *
3612  *
3613  * Return Value:
3614  *    A ptr to frame or NULL on allocation failure
3615  *
3616  -*/
3617
3618
3619 PSTxMgmtPacket
3620 s_MgrMakeAssocRequest(
3621         PSDevice pDevice,
3622         PSMgmtObject pMgmt,
3623         unsigned char *pDAddr,
3624         unsigned short wCurrCapInfo,
3625         unsigned short wListenInterval,
3626         PWLAN_IE_SSID pCurrSSID,
3627         PWLAN_IE_SUPP_RATES pCurrRates,
3628         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3629 )
3630 {
3631         PSTxMgmtPacket      pTxPacket = NULL;
3632         WLAN_FR_ASSOCREQ    sFrame;
3633         unsigned char *pbyIEs;
3634         unsigned char *pbyRSN;
3635
3636
3637         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3638         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3639         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3640         // Setup the sFrame structure.
3641         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3642         sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
3643         // format fixed field frame structure
3644         vMgrEncodeAssocRequest(&sFrame);
3645         // Setup the header
3646         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3647                 (
3648                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3649                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
3650 ));
3651         memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3652         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3653         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3654
3655         // Set the capability and listen interval
3656         *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3657         *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3658
3659         // sFrame.len point to end of fixed field
3660         sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3661         sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3662         memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3663
3664         pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3665         pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3666         pbyIEs = pMgmt->sAssocInfo.abyIEs;
3667         memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3668         pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3669
3670         // Copy the rate set
3671         sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3672         if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4))
3673                 sFrame.len += 4 + WLAN_IEHDR_LEN;
3674         else
3675                 sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3676         memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3677
3678         // Copy the extension rate set
3679         if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3680                 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3681                 sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3682                 memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3683         }
3684
3685         pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3686         memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3687         pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3688
3689         // for 802.11h
3690         if (pMgmt->b11hEnable == true) {
3691                 if (sFrame.pCurrPowerCap == NULL) {
3692                         sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len);
3693                         sFrame.len += (2 + WLAN_IEHDR_LEN);
3694                         sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY;
3695                         sFrame.pCurrPowerCap->len = 2;
3696                         CARDvGetPowerCapability(pMgmt->pAdapter,
3697                                                 &(sFrame.pCurrPowerCap->byMinPower),
3698                                                 &(sFrame.pCurrPowerCap->byMaxPower)
3699 );
3700                 }
3701                 if (sFrame.pCurrSuppCh == NULL) {
3702                         sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len);
3703                         sFrame.len += set_support_channels(pMgmt->pAdapter, (unsigned char *)sFrame.pCurrSuppCh);
3704                 }
3705         }
3706
3707         if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3708              (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3709              (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3710             (pMgmt->pCurrBSS != NULL)) {
3711                 /* WPA IE */
3712                 sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3713                 sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3714                 sFrame.pRSNWPA->len = 16;
3715                 sFrame.pRSNWPA->abyOUI[0] = 0x00;
3716                 sFrame.pRSNWPA->abyOUI[1] = 0x50;
3717                 sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3718                 sFrame.pRSNWPA->abyOUI[3] = 0x01;
3719                 sFrame.pRSNWPA->wVersion = 1;
3720                 //Group Key Cipher Suite
3721                 sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3722                 sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3723                 sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3724                 if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3725                         sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3726                 } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3727                         sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3728                 } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3729                         sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3730                 } else {
3731                         sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3732                 }
3733                 // Pairwise Key Cipher Suite
3734                 sFrame.pRSNWPA->wPKCount = 1;
3735                 sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3736                 sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3737                 sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3738                 if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3739                         sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3740                 } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3741                         sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3742                 } else {
3743                         sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3744                 }
3745                 // Auth Key Management Suite
3746                 pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3747                 *pbyRSN++ = 0x01;
3748                 *pbyRSN++ = 0x00;
3749                 *pbyRSN++ = 0x00;
3750
3751                 *pbyRSN++ = 0x50;
3752                 *pbyRSN++ = 0xf2;
3753                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
3754                         *pbyRSN++ = WPA_AUTH_PSK;
3755                 }
3756                 else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
3757                         *pbyRSN++ = WPA_AUTH_IEEE802_1X;
3758                 }
3759                 else {
3760                         *pbyRSN++ = WPA_NONE;
3761                 }
3762
3763                 sFrame.pRSNWPA->len += 6;
3764
3765                 // RSN Capabilities
3766
3767                 *pbyRSN++ = 0x00;
3768                 *pbyRSN++ = 0x00;
3769                 sFrame.pRSNWPA->len += 2;
3770
3771                 sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3772                 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3773                 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3774                 memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3775                 pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3776
3777         } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3778                     (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3779                    (pMgmt->pCurrBSS != NULL)) {
3780                 unsigned int ii;
3781                 unsigned short *pwPMKID;
3782
3783                 // WPA IE
3784                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3785                 sFrame.pRSN->byElementID = WLAN_EID_RSN;
3786                 sFrame.pRSN->len = 6; //Version(2)+GK(4)
3787                 sFrame.pRSN->wVersion = 1;
3788                 //Group Key Cipher Suite
3789                 sFrame.pRSN->abyRSN[0] = 0x00;
3790                 sFrame.pRSN->abyRSN[1] = 0x0F;
3791                 sFrame.pRSN->abyRSN[2] = 0xAC;
3792                 if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3793                         sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3794                 } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3795                         sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3796                 } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3797                         sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3798                 } else {
3799                         sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3800                 }
3801
3802                 // Pairwise Key Cipher Suite
3803                 sFrame.pRSN->abyRSN[4] = 1;
3804                 sFrame.pRSN->abyRSN[5] = 0;
3805                 sFrame.pRSN->abyRSN[6] = 0x00;
3806                 sFrame.pRSN->abyRSN[7] = 0x0F;
3807                 sFrame.pRSN->abyRSN[8] = 0xAC;
3808                 if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3809                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3810                 } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3811                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3812                 } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
3813                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3814                 } else {
3815                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3816                 }
3817                 sFrame.pRSN->len += 6;
3818
3819                 // Auth Key Management Suite
3820                 sFrame.pRSN->abyRSN[10] = 1;
3821                 sFrame.pRSN->abyRSN[11] = 0;
3822                 sFrame.pRSN->abyRSN[12] = 0x00;
3823                 sFrame.pRSN->abyRSN[13] = 0x0F;
3824                 sFrame.pRSN->abyRSN[14] = 0xAC;
3825                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
3826                         sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3827                 } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
3828                         sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3829                 } else {
3830                         sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3831                 }
3832                 sFrame.pRSN->len += 6;
3833
3834                 // RSN Capabilities
3835                 if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
3836                         memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3837                 } else {
3838                         sFrame.pRSN->abyRSN[16] = 0;
3839                         sFrame.pRSN->abyRSN[17] = 0;
3840                 }
3841                 sFrame.pRSN->len += 2;
3842
3843                 if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3844                         // RSN PMKID
3845                         pbyRSN = &sFrame.pRSN->abyRSN[18];
3846                         pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
3847                         *pwPMKID = 0;            // Initialize PMKID count
3848                         pbyRSN += 2;             // Point to PMKID list
3849                         for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3850                                 if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) {
3851                                         (*pwPMKID)++;
3852                                         memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
3853                                         pbyRSN += 16;
3854                                 }
3855                         }
3856                         if (*pwPMKID != 0) {
3857                                 sFrame.pRSN->len += (2 + (*pwPMKID)*16);
3858                         }
3859                 }
3860
3861                 sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3862                 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3863                 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3864                 memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
3865                 pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3866         }
3867
3868
3869         // Adjust the length fields
3870         pTxPacket->cbMPDULen = sFrame.len;
3871         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3872         return pTxPacket;
3873 }
3874
3875
3876
3877
3878
3879
3880
3881
3882 /*+
3883  *
3884  * Routine Description:
3885  *  Constructs an re-association request frame
3886  *
3887  *
3888  * Return Value:
3889  *    A ptr to frame or NULL on allocation failure
3890  *
3891  -*/
3892
3893
3894 PSTxMgmtPacket
3895 s_MgrMakeReAssocRequest(
3896         PSDevice pDevice,
3897         PSMgmtObject pMgmt,
3898         unsigned char *pDAddr,
3899         unsigned short wCurrCapInfo,
3900         unsigned short wListenInterval,
3901         PWLAN_IE_SSID pCurrSSID,
3902         PWLAN_IE_SUPP_RATES pCurrRates,
3903         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3904 )
3905 {
3906         PSTxMgmtPacket      pTxPacket = NULL;
3907         WLAN_FR_REASSOCREQ  sFrame;
3908         unsigned char *pbyIEs;
3909         unsigned char *pbyRSN;
3910
3911
3912         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3913         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
3914         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3915         /* Setup the sFrame structure. */
3916         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3917         sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
3918
3919         // format fixed field frame structure
3920         vMgrEncodeReassocRequest(&sFrame);
3921
3922         /* Setup the header */
3923         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3924                 (
3925                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3926                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
3927 ));
3928         memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3929         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3930         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3931
3932         /* Set the capability and listen interval */
3933         *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3934         *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3935
3936         memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3937         /* Copy the SSID */
3938         /* sFrame.len point to end of fixed field */
3939         sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3940         sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3941         memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3942
3943         pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3944         pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3945         pbyIEs = pMgmt->sAssocInfo.abyIEs;
3946         memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3947         pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3948
3949         /* Copy the rate set */
3950         /* sFrame.len point to end of SSID */
3951         sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3952         sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3953         memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3954
3955         // Copy the extension rate set
3956         if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3957                 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3958                 sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3959                 memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3960         }
3961
3962         pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3963         memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3964         pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3965
3966         if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3967              (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3968              (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3969             (pMgmt->pCurrBSS != NULL)) {
3970                 /* WPA IE */
3971                 sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3972                 sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3973                 sFrame.pRSNWPA->len = 16;
3974                 sFrame.pRSNWPA->abyOUI[0] = 0x00;
3975                 sFrame.pRSNWPA->abyOUI[1] = 0x50;
3976                 sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3977                 sFrame.pRSNWPA->abyOUI[3] = 0x01;
3978                 sFrame.pRSNWPA->wVersion = 1;
3979                 //Group Key Cipher Suite
3980                 sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3981                 sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3982                 sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3983                 if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3984                         sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3985                 } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3986                         sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3987                 } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3988                         sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3989                 } else {
3990                         sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3991                 }
3992                 // Pairwise Key Cipher Suite
3993                 sFrame.pRSNWPA->wPKCount = 1;
3994                 sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3995                 sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3996                 sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3997                 if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3998                         sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3999                 } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
4000                         sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
4001                 } else {
4002                         sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
4003                 }
4004                 // Auth Key Management Suite
4005                 pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
4006                 *pbyRSN++ = 0x01;
4007                 *pbyRSN++ = 0x00;
4008                 *pbyRSN++ = 0x00;
4009
4010                 *pbyRSN++ = 0x50;
4011                 *pbyRSN++ = 0xf2;
4012                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
4013                         *pbyRSN++ = WPA_AUTH_PSK;
4014                 } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
4015                         *pbyRSN++ = WPA_AUTH_IEEE802_1X;
4016                 } else {
4017                         *pbyRSN++ = WPA_NONE;
4018                 }
4019
4020                 sFrame.pRSNWPA->len += 6;
4021
4022                 // RSN Capabilities
4023                 *pbyRSN++ = 0x00;
4024                 *pbyRSN++ = 0x00;
4025                 sFrame.pRSNWPA->len += 2;
4026
4027                 sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
4028                 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
4029                 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
4030                 memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
4031                 pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
4032
4033         } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
4034                     (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
4035                    (pMgmt->pCurrBSS != NULL)) {
4036                 unsigned int ii;
4037                 unsigned short *pwPMKID;
4038
4039                 /* WPA IE */
4040                 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
4041                 sFrame.pRSN->byElementID = WLAN_EID_RSN;
4042                 sFrame.pRSN->len = 6; //Version(2)+GK(4)
4043                 sFrame.pRSN->wVersion = 1;
4044                 //Group Key Cipher Suite
4045                 sFrame.pRSN->abyRSN[0] = 0x00;
4046                 sFrame.pRSN->abyRSN[1] = 0x0F;
4047                 sFrame.pRSN->abyRSN[2] = 0xAC;
4048                 if (pMgmt->byCSSGK == KEY_CTL_WEP) {
4049                         sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
4050                 } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
4051                         sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
4052                 } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
4053                         sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
4054                 } else {
4055                         sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
4056                 }
4057
4058                 // Pairwise Key Cipher Suite
4059                 sFrame.pRSN->abyRSN[4] = 1;
4060                 sFrame.pRSN->abyRSN[5] = 0;
4061                 sFrame.pRSN->abyRSN[6] = 0x00;
4062                 sFrame.pRSN->abyRSN[7] = 0x0F;
4063                 sFrame.pRSN->abyRSN[8] = 0xAC;
4064                 if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
4065                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
4066                 } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
4067                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
4068                 } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
4069                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
4070                 } else {
4071                         sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
4072                 }
4073                 sFrame.pRSN->len += 6;
4074
4075                 // Auth Key Management Suite
4076                 sFrame.pRSN->abyRSN[10] = 1;
4077                 sFrame.pRSN->abyRSN[11] = 0;
4078                 sFrame.pRSN->abyRSN[12] = 0x00;
4079                 sFrame.pRSN->abyRSN[13] = 0x0F;
4080                 sFrame.pRSN->abyRSN[14] = 0xAC;
4081                 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
4082                         sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
4083                 } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
4084                         sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
4085                 } else {
4086                         sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
4087                 }
4088                 sFrame.pRSN->len += 6;
4089
4090                 // RSN Capabilities
4091                 if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == true) {
4092                         memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
4093                 } else {
4094                         sFrame.pRSN->abyRSN[16] = 0;
4095                         sFrame.pRSN->abyRSN[17] = 0;
4096                 }
4097                 sFrame.pRSN->len += 2;
4098
4099                 if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == true) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
4100                         // RSN PMKID
4101                         pbyRSN = &sFrame.pRSN->abyRSN[18];
4102                         pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
4103                         *pwPMKID = 0;            // Initialize PMKID count
4104                         pbyRSN += 2;             // Point to PMKID list
4105                         for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
4106                                 if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) {
4107                                         (*pwPMKID)++;
4108                                         memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
4109                                         pbyRSN += 16;
4110                                 }
4111                         }
4112                         if (*pwPMKID != 0) {
4113                                 sFrame.pRSN->len += (2 + (*pwPMKID) * 16);
4114                         }
4115                 }
4116
4117                 sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
4118                 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
4119                 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
4120                 memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
4121                 pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
4122         }
4123
4124
4125         /* Adjust the length fields */
4126         pTxPacket->cbMPDULen = sFrame.len;
4127         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4128
4129         return pTxPacket;
4130 }
4131
4132
4133
4134 /*+
4135  *
4136  * Routine Description:
4137  *  Constructs an assoc-response frame
4138  *
4139  *
4140  * Return Value:
4141  *    PTR to frame; or NULL on allocation failure
4142  *
4143  -*/
4144
4145
4146 PSTxMgmtPacket
4147 s_MgrMakeAssocResponse(
4148         PSDevice pDevice,
4149         PSMgmtObject pMgmt,
4150         unsigned short wCurrCapInfo,
4151         unsigned short wAssocStatus,
4152         unsigned short wAssocAID,
4153         unsigned char *pDstAddr,
4154         PWLAN_IE_SUPP_RATES pCurrSuppRates,
4155         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
4156 )
4157 {
4158         PSTxMgmtPacket      pTxPacket = NULL;
4159         WLAN_FR_ASSOCRESP   sFrame;
4160
4161
4162         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
4163         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
4164         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
4165         // Setup the sFrame structure
4166         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
4167         sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
4168         vMgrEncodeAssocResponse(&sFrame);
4169         // Setup the header
4170         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
4171                 (
4172                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
4173                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
4174 ));
4175         memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
4176         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
4177         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
4178
4179         *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
4180         *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
4181         *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
4182
4183         // Copy the rate set
4184         sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4185         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
4186         memcpy(sFrame.pSuppRates,
4187                pCurrSuppRates,
4188                ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
4189 );
4190
4191         if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
4192                 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4193                 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
4194                 memcpy(sFrame.pExtSuppRates,
4195                        pCurrExtSuppRates,
4196                        ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
4197 );
4198         }
4199
4200         // Adjust the length fields
4201         pTxPacket->cbMPDULen = sFrame.len;
4202         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4203
4204         return pTxPacket;
4205 }
4206
4207
4208 /*+
4209  *
4210  * Routine Description:
4211  *  Constructs an reassoc-response frame
4212  *
4213  *
4214  * Return Value:
4215  *    PTR to frame; or NULL on allocation failure
4216  *
4217  -*/
4218
4219
4220 PSTxMgmtPacket
4221 s_MgrMakeReAssocResponse(
4222         PSDevice pDevice,
4223         PSMgmtObject pMgmt,
4224         unsigned short wCurrCapInfo,
4225         unsigned short wAssocStatus,
4226         unsigned short wAssocAID,
4227         unsigned char *pDstAddr,
4228         PWLAN_IE_SUPP_RATES pCurrSuppRates,
4229         PWLAN_IE_SUPP_RATES pCurrExtSuppRates
4230 )
4231 {
4232         PSTxMgmtPacket      pTxPacket = NULL;
4233         WLAN_FR_REASSOCRESP   sFrame;
4234
4235
4236         pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
4237         memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
4238         pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
4239         // Setup the sFrame structure
4240         sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
4241         sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
4242         vMgrEncodeReassocResponse(&sFrame);
4243         // Setup the header
4244         sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
4245                 (
4246                         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
4247                         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
4248 ));
4249         memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
4250         memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
4251         memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
4252
4253         *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
4254         *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
4255         *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
4256
4257         // Copy the rate set
4258         sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4259         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
4260         memcpy(sFrame.pSuppRates,
4261                pCurrSuppRates,
4262                ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
4263 );
4264
4265         if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
4266                 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4267                 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
4268                 memcpy(sFrame.pExtSuppRates,
4269                        pCurrExtSuppRates,
4270                        ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
4271 );
4272         }
4273
4274         // Adjust the length fields
4275         pTxPacket->cbMPDULen = sFrame.len;
4276         pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4277
4278         return pTxPacket;
4279 }
4280
4281
4282 /*+
4283  *
4284  * Routine Description:
4285  *  Handles probe response management frames.
4286  *
4287  *
4288  * Return Value:
4289  *    none.
4290  *
4291  -*/
4292
4293 static
4294 void
4295 s_vMgrRxProbeResponse(
4296         PSDevice pDevice,
4297         PSMgmtObject pMgmt,
4298         PSRxMgmtPacket pRxPacket
4299 )
4300 {
4301         PKnownBSS           pBSSList = NULL;
4302         WLAN_FR_PROBERESP   sFrame;
4303         unsigned char byCurrChannel = pRxPacket->byRxChannel;
4304         ERPObject           sERP;
4305         unsigned char byIEChannel = 0;
4306         bool bChannelHit = true;
4307
4308
4309         memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
4310         // decode the frame
4311         sFrame.len = pRxPacket->cbMPDULen;
4312         sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
4313         vMgrDecodeProbeResponse(&sFrame);
4314
4315         if ((sFrame.pqwTimestamp == 0) ||
4316             (sFrame.pwBeaconInterval == 0) ||
4317             (sFrame.pwCapInfo == 0) ||
4318             (sFrame.pSSID == 0) ||
4319             (sFrame.pSuppRates == 0)) {
4320                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
4321                 DBG_PORT80(0xCC);
4322                 return;
4323         }
4324
4325         if (sFrame.pSSID->len == 0)
4326                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
4327
4328         if (sFrame.pDSParms != 0) {
4329                 if (byCurrChannel > CB_MAX_CHANNEL_24G) {
4330                         // channel remapping to
4331                         byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
4332                 } else {
4333                         byIEChannel = sFrame.pDSParms->byCurrChannel;
4334                 }
4335                 if (byCurrChannel != byIEChannel) {
4336                         // adjust channel info. bcs we rcv adjacent channel packets
4337                         bChannelHit = false;
4338                         byCurrChannel = byIEChannel;
4339                 }
4340         } else {
4341                 // no DS channel info
4342                 bChannelHit = true;
4343         }
4344
4345 //2008-0730-01<Add>by MikeLiu
4346         if (ChannelExceedZoneType(pDevice, byCurrChannel) == true)
4347                 return;
4348
4349         if (sFrame.pERP != NULL) {
4350                 sERP.byERP = sFrame.pERP->byContext;
4351                 sERP.bERPExist = true;
4352         } else {
4353                 sERP.bERPExist = false;
4354                 sERP.byERP = 0;
4355         }
4356
4357
4358         // update or insert the bss
4359         pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
4360         if (pBSSList) {
4361                 BSSbUpdateToBSSList((void *)pDevice,
4362                                     *sFrame.pqwTimestamp,
4363                                     *sFrame.pwBeaconInterval,
4364                                     *sFrame.pwCapInfo,
4365                                     byCurrChannel,
4366                                     bChannelHit,
4367                                     sFrame.pSSID,
4368                                     sFrame.pSuppRates,
4369                                     sFrame.pExtSuppRates,
4370                                     &sERP,
4371                                     sFrame.pRSN,
4372                                     sFrame.pRSNWPA,
4373                                     sFrame.pIE_Country,
4374                                     sFrame.pIE_Quiet,
4375                                     pBSSList,
4376                                     sFrame.len - WLAN_HDR_ADDR3_LEN,
4377                                     sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
4378                                     (void *)pRxPacket
4379 );
4380         }
4381         else {
4382                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
4383                 BSSbInsertToBSSList((void *)pDevice,
4384                                     sFrame.pHdr->sA3.abyAddr3,
4385                                     *sFrame.pqwTimestamp,
4386                                     *sFrame.pwBeaconInterval,
4387                                     *sFrame.pwCapInfo,
4388                                     byCurrChannel,
4389                                     sFrame.pSSID,
4390                                     sFrame.pSuppRates,
4391                                     sFrame.pExtSuppRates,
4392                                     &sERP,
4393                                     sFrame.pRSN,
4394                                     sFrame.pRSNWPA,
4395                                     sFrame.pIE_Country,
4396                                     sFrame.pIE_Quiet,
4397                                     sFrame.len - WLAN_HDR_ADDR3_LEN,
4398                                     sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
4399                                     (void *)pRxPacket
4400 );
4401         }
4402         return;
4403
4404 }
4405
4406 /*+
4407  *
4408  * Routine Description:(AP)or(Ad-hoc STA)
4409  *  Handles probe request management frames.
4410  *
4411  *
4412  * Return Value:
4413  *    none.
4414  *
4415  -*/
4416
4417
4418 static
4419 void
4420 s_vMgrRxProbeRequest(
4421         PSDevice pDevice,
4422         PSMgmtObject pMgmt,
4423         PSRxMgmtPacket pRxPacket
4424 )
4425 {
4426         WLAN_FR_PROBEREQ    sFrame;
4427         CMD_STATUS          Status;
4428         PSTxMgmtPacket      pTxPacket;
4429         unsigned char byPHYType = BB_TYPE_11B;
4430
4431         // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
4432         // STA have to response this request.
4433         if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
4434             ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
4435
4436                 memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
4437                 // decode the frame
4438                 sFrame.len = pRxPacket->cbMPDULen;
4439                 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
4440                 vMgrDecodeProbeRequest(&sFrame);
4441 /*
4442   DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n",
4443   sFrame.pHdr->sA3.abyAddr2);
4444 */
4445                 if (sFrame.pSSID->len != 0) {
4446                         if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
4447                                 return;
4448                         if (memcmp(sFrame.pSSID->abySSID,
4449                                    ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
4450                                    ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
4451                                 return;
4452                         }
4453                 }
4454
4455                 if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) {
4456                         byPHYType = BB_TYPE_11G;
4457                 }
4458
4459                 // Probe response reply..
4460                 pTxPacket = s_MgrMakeProbeResponse
4461                         (
4462                                 pDevice,
4463                                 pMgmt,
4464                                 pMgmt->wCurrCapInfo,
4465                                 pMgmt->wCurrBeaconPeriod,
4466                                 pMgmt->uCurrChannel,
4467                                 0,
4468                                 sFrame.pHdr->sA3.abyAddr2,
4469                                 (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4470                                 (unsigned char *)pMgmt->abyCurrBSSID,
4471                                 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4472                                 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
4473                                 byPHYType
4474 );
4475                 if (pTxPacket != NULL) {
4476                         /* send the frame */
4477                         Status = csMgmt_xmit(pDevice, pTxPacket);
4478                         if (Status != CMD_STATUS_PENDING) {
4479                                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
4480                         }
4481                         else {
4482 //                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
4483                         }
4484                 }
4485         }
4486
4487         return;
4488 }
4489
4490
4491
4492
4493
4494 /*+
4495  *
4496  * Routine Description:
4497  *
4498  *  Entry point for the reception and handling of 802.11 management
4499  *  frames. Makes a determination of the frame type and then calls
4500  *  the appropriate function.
4501  *
4502  *
4503  * Return Value:
4504  *    none.
4505  *
4506  -*/
4507
4508
4509 void
4510 vMgrRxManagePacket(
4511         void *hDeviceContext,
4512         PSMgmtObject pMgmt,
4513         PSRxMgmtPacket pRxPacket
4514 )
4515 {
4516         PSDevice    pDevice = (PSDevice)hDeviceContext;
4517         bool bInScan = false;
4518         unsigned int uNodeIndex = 0;
4519         NODE_STATE  eNodeState = 0;
4520         CMD_STATUS  Status;
4521
4522
4523         if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
4524                 if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
4525                         eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
4526         }
4527
4528         switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) {
4529
4530         case WLAN_FSTYPE_ASSOCREQ:
4531                 // Frame Clase = 2
4532                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
4533                 if (eNodeState < NODE_AUTH) {
4534                         // send deauth notification
4535                         // reason = (6) class 2 received from nonauth sta
4536                         vMgrDeAuthenBeginSta(pDevice,
4537                                              pMgmt,
4538                                              pRxPacket->p80211Header->sA3.abyAddr2,
4539                                              (6),
4540                                              &Status
4541 );
4542                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
4543                 }
4544                 else {
4545                         s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4546                 }
4547                 break;
4548
4549         case WLAN_FSTYPE_ASSOCRESP:
4550                 // Frame Clase = 2
4551                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
4552                 s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false);
4553                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
4554                 break;
4555
4556         case WLAN_FSTYPE_REASSOCREQ:
4557                 // Frame Clase = 2
4558                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
4559                 // Todo: reassoc
4560                 if (eNodeState < NODE_AUTH) {
4561                         // send deauth notification
4562                         // reason = (6) class 2 received from nonauth sta
4563                         vMgrDeAuthenBeginSta(pDevice,
4564                                              pMgmt,
4565                                              pRxPacket->p80211Header->sA3.abyAddr2,
4566                                              (6),
4567                                              &Status
4568 );
4569                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
4570
4571                 }
4572                 s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4573                 break;
4574
4575         case WLAN_FSTYPE_REASSOCRESP:
4576                 // Frame Clase = 2
4577                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
4578                 s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true);
4579                 break;
4580
4581         case WLAN_FSTYPE_PROBEREQ:
4582                 // Frame Clase = 0
4583                 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
4584                 s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
4585                 break;
4586
4587         case WLAN_FSTYPE_PROBERESP:
4588                 // Frame Clase = 0
4589                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
4590
4591                 s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
4592                 break;
4593
4594         case WLAN_FSTYPE_BEACON:
4595                 // Frame Clase = 0
4596                 //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
4597                 if (pMgmt->eScanState != WMAC_NO_SCANNING) {
4598                         bInScan = true;
4599                 }
4600                 s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
4601                 break;
4602
4603         case WLAN_FSTYPE_ATIM:
4604                 // Frame Clase = 1
4605                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
4606                 break;
4607
4608         case WLAN_FSTYPE_DISASSOC:
4609                 // Frame Clase = 2
4610                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
4611                 if (eNodeState < NODE_AUTH) {
4612                         // send deauth notification
4613                         // reason = (6) class 2 received from nonauth sta
4614                         vMgrDeAuthenBeginSta(pDevice,
4615                                              pMgmt,
4616                                              pRxPacket->p80211Header->sA3.abyAddr2,
4617                                              (6),
4618                                              &Status
4619 );
4620                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
4621                 }
4622                 s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
4623                 break;
4624
4625         case WLAN_FSTYPE_AUTHEN:
4626                 // Frame Clase = 1
4627                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
4628                 s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
4629                 break;
4630
4631         case WLAN_FSTYPE_DEAUTHEN:
4632                 // Frame Clase = 1
4633                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
4634                 s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
4635                 break;
4636
4637         default:
4638                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
4639         }
4640
4641         return;
4642 }
4643
4644
4645
4646
4647 /*+
4648  *
4649  * Routine Description:
4650  *
4651  *
4652  *  Prepare beacon to send
4653  *
4654  * Return Value:
4655  *    true if success; false if failed.
4656  *
4657  -*/
4658 bool
4659 bMgrPrepareBeaconToSend(
4660         void *hDeviceContext,
4661         PSMgmtObject pMgmt
4662 )
4663 {
4664         PSDevice            pDevice = (PSDevice)hDeviceContext;
4665         PSTxMgmtPacket      pTxPacket;
4666
4667 //    pDevice->bBeaconBufReady = false;
4668         if (pDevice->bEncryptionEnable || pDevice->bEnable8021x) {
4669                 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
4670         }
4671         else {
4672                 pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
4673         }
4674         pTxPacket = s_MgrMakeBeacon
4675                 (
4676                         pDevice,
4677                         pMgmt,
4678                         pMgmt->wCurrCapInfo,
4679                         pMgmt->wCurrBeaconPeriod,
4680                         pMgmt->uCurrChannel,
4681                         pMgmt->wCurrATIMWindow, //0,
4682                         (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4683                         (unsigned char *)pMgmt->abyCurrBSSID,
4684                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4685                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
4686 );
4687
4688         if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
4689             (pMgmt->abyCurrBSSID[0] == 0))
4690                 return false;
4691
4692         csBeacon_xmit(pDevice, pTxPacket);
4693
4694         return true;
4695 }
4696
4697
4698
4699
4700 /*+
4701  *
4702  * Routine Description:
4703  *
4704  *  Log a warning message based on the contents of the Status
4705  *  Code field of an 802.11 management frame.  Defines are
4706  *  derived from 802.11-1997 SPEC.
4707  *
4708  * Return Value:
4709  *    none.
4710  *
4711  -*/
4712 static
4713 void
4714 s_vMgrLogStatus(
4715         PSMgmtObject pMgmt,
4716         unsigned short wStatus
4717 )
4718 {
4719         switch (wStatus) {
4720         case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
4721                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
4722                 break;
4723         case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
4724                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
4725                 break;
4726         case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
4727                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
4728                 break;
4729         case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
4730                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
4731                 break;
4732         case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
4733                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
4734                 break;
4735         case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
4736                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
4737                 break;
4738         case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
4739                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
4740                 break;
4741         case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
4742                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
4743                 break;
4744         case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
4745                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
4746                 break;
4747         case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
4748                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
4749                 break;
4750         case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
4751                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
4752                 break;
4753         case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
4754                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
4755                 break;
4756         case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
4757                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
4758                 break;
4759         default:
4760                 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
4761                 break;
4762         }
4763 }
4764
4765
4766 /*
4767  *
4768  * Description:
4769  *    Add BSSID in PMKID Candidate list.
4770  *
4771  * Parameters:
4772  *  In:
4773  *      hDeviceContext - device structure point
4774  *      pbyBSSID - BSSID address for adding
4775  *      wRSNCap - BSS's RSN capability
4776  *  Out:
4777  *      none
4778  *
4779  * Return Value: none.
4780  *
4781  -*/
4782 bool
4783 bAdd_PMKID_Candidate(
4784         void *hDeviceContext,
4785         unsigned char *pbyBSSID,
4786         PSRSNCapObject psRSNCapObj
4787 )
4788 {
4789         PSDevice         pDevice = (PSDevice)hDeviceContext;
4790         PPMKID_CANDIDATE pCandidateList;
4791         unsigned int ii = 0;
4792
4793         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4794
4795         if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
4796                 return false;
4797
4798         if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
4799                 return false;
4800
4801
4802
4803         // Update Old Candidate
4804         for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
4805                 pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
4806                 if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
4807                         if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
4808                                 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4809                         } else {
4810                                 pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4811                         }
4812                         return true;
4813                 }
4814         }
4815
4816         // New Candidate
4817         pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
4818         if ((psRSNCapObj->bRSNCapExist == true) && (psRSNCapObj->wRSNCap & BIT0)) {
4819                 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4820         } else {
4821                 pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4822         }
4823         memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
4824         pDevice->gsPMKIDCandidate.NumCandidates++;
4825         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4826         return true;
4827 }
4828
4829 /*
4830  *
4831  * Description:
4832  *    Flush PMKID Candidate list.
4833  *
4834  * Parameters:
4835  *  In:
4836  *      hDeviceContext - device structure point
4837  *  Out:
4838  *      none
4839  *
4840  * Return Value: none.
4841  *
4842  -*/
4843 void
4844 vFlush_PMKID_Candidate(
4845         void *hDeviceContext
4846 )
4847 {
4848         PSDevice        pDevice = (PSDevice)hDeviceContext;
4849
4850         if (pDevice == NULL)
4851                 return;
4852
4853         memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
4854 }
4855
4856 static bool
4857 s_bCipherMatch(
4858         PKnownBSS                        pBSSNode,
4859         NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
4860         unsigned char *pbyCCSPK,
4861         unsigned char *pbyCCSGK
4862 )
4863 {
4864         unsigned char byMulticastCipher = KEY_CTL_INVALID;
4865         unsigned char byCipherMask = 0x00;
4866         int i;
4867
4868         if (pBSSNode == NULL)
4869                 return false;
4870
4871         // check cap. of BSS
4872         if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4873             (EncStatus == Ndis802_11Encryption1Enabled)) {
4874                 // default is WEP only
4875                 byMulticastCipher = KEY_CTL_WEP;
4876         }
4877
4878         if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4879             (pBSSNode->bWPA2Valid == true) &&
4880             //20080123-01,<Add> by Einsn Liu
4881             ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
4882                 //WPA2
4883                 // check Group Key Cipher
4884                 if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
4885                     (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
4886                         byMulticastCipher = KEY_CTL_WEP;
4887                 } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
4888                         byMulticastCipher = KEY_CTL_TKIP;
4889                 } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
4890                         byMulticastCipher = KEY_CTL_CCMP;
4891                 } else {
4892                         byMulticastCipher = KEY_CTL_INVALID;
4893                 }
4894
4895                 // check Pairwise Key Cipher
4896                 for (i = 0; i < pBSSNode->wCSSPKCount; i++) {
4897                         if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
4898                             (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
4899                                 // this should not happen as defined 802.11i
4900                                 byCipherMask |= 0x01;
4901                         } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
4902                                 byCipherMask |= 0x02;
4903                         } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
4904                                 byCipherMask |= 0x04;
4905                         } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
4906                                 // use group key only ignore all others
4907                                 byCipherMask = 0;
4908                                 i = pBSSNode->wCSSPKCount;
4909                         }
4910                 }
4911
4912         } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4913                    (pBSSNode->bWPAValid == true) &&
4914                    ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
4915                 //WPA
4916                 // check Group Key Cipher
4917                 if ((pBSSNode->byGKType == WPA_WEP40) ||
4918                     (pBSSNode->byGKType == WPA_WEP104)) {
4919                         byMulticastCipher = KEY_CTL_WEP;
4920                 } else if (pBSSNode->byGKType == WPA_TKIP) {
4921                         byMulticastCipher = KEY_CTL_TKIP;
4922                 } else if (pBSSNode->byGKType == WPA_AESCCMP) {
4923                         byMulticastCipher = KEY_CTL_CCMP;
4924                 } else {
4925                         byMulticastCipher = KEY_CTL_INVALID;
4926                 }
4927
4928                 // check Pairwise Key Cipher
4929                 for (i = 0; i < pBSSNode->wPKCount; i++) {
4930                         if (pBSSNode->abyPKType[i] == WPA_TKIP) {
4931                                 byCipherMask |= 0x02;
4932                         } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
4933                                 byCipherMask |= 0x04;
4934                         } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
4935                                 // use group key only ignore all others
4936                                 byCipherMask = 0;
4937                                 i = pBSSNode->wPKCount;
4938                         }
4939                 }
4940         }
4941
4942         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%d, %d, %d, %d, EncStatus:%d\n",
4943                 byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
4944
4945         // mask our cap. with BSS
4946         if (EncStatus == Ndis802_11Encryption1Enabled) {
4947
4948                 // For supporting Cisco migration mode, don't care pairwise key cipher
4949                 if ((byMulticastCipher == KEY_CTL_WEP) &&
4950                     (byCipherMask == 0)) {
4951                         *pbyCCSGK = KEY_CTL_WEP;
4952                         *pbyCCSPK = KEY_CTL_NONE;
4953                         return true;
4954                 } else {
4955                         return false;
4956                 }
4957
4958         } else if (EncStatus == Ndis802_11Encryption2Enabled) {
4959                 if ((byMulticastCipher == KEY_CTL_TKIP) &&
4960                     (byCipherMask == 0)) {
4961                         *pbyCCSGK = KEY_CTL_TKIP;
4962                         *pbyCCSPK = KEY_CTL_NONE;
4963                         return true;
4964                 } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4965                            ((byCipherMask & 0x02) != 0)) {
4966                         *pbyCCSGK = KEY_CTL_WEP;
4967                         *pbyCCSPK = KEY_CTL_TKIP;
4968                         return true;
4969                 } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4970                            ((byCipherMask & 0x02) != 0)) {
4971                         *pbyCCSGK = KEY_CTL_TKIP;
4972                         *pbyCCSPK = KEY_CTL_TKIP;
4973                         return true;
4974                 } else {
4975                         return false;
4976                 }
4977         } else if (EncStatus == Ndis802_11Encryption3Enabled) {
4978                 if ((byMulticastCipher == KEY_CTL_CCMP) &&
4979                     (byCipherMask == 0)) {
4980                         // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
4981                         return false;
4982                 } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4983                            ((byCipherMask & 0x04) != 0)) {
4984                         *pbyCCSGK = KEY_CTL_WEP;
4985                         *pbyCCSPK = KEY_CTL_CCMP;
4986                         return true;
4987                 } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4988                            ((byCipherMask & 0x04) != 0)) {
4989                         *pbyCCSGK = KEY_CTL_TKIP;
4990                         *pbyCCSPK = KEY_CTL_CCMP;
4991                         return true;
4992                 } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
4993                            ((byCipherMask & 0x04) != 0)) {
4994                         *pbyCCSGK = KEY_CTL_CCMP;
4995                         *pbyCCSPK = KEY_CTL_CCMP;
4996                         return true;
4997                 } else {
4998                         return false;
4999                 }
5000         }
5001         return true;
5002 }
5003
5004