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