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