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