Merge branch 'for-2.6.40/core' of git://git.kernel.dk/linux-2.6-block
[firefly-linux-kernel-4.4.55.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
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
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
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 /*+
1749  *
1750  * Routine Description:
1751  * check if current channel is match ZoneType.
1752  *for USA:1~11;
1753  *      Japan:1~13;
1754  *      Europe:1~13
1755  * Return Value:
1756  *               True:exceed;
1757  *                False:normal case
1758 -*/
1759 static BOOL
1760 ChannelExceedZoneType(
1761      PSDevice pDevice,
1762      BYTE byCurrChannel
1763     )
1764 {
1765   BOOL exceed=FALSE;
1766
1767   switch(pDevice->byZoneType) {
1768         case 0x00:                  //USA:1~11
1769                      if((byCurrChannel<1) ||(byCurrChannel>11))
1770                         exceed = TRUE;
1771                  break;
1772         case 0x01:                  //Japan:1~13
1773         case 0x02:                  //Europe:1~13
1774                      if((byCurrChannel<1) ||(byCurrChannel>13))
1775                         exceed = TRUE;
1776                  break;
1777         default:                    //reserve for other zonetype
1778                 break;
1779   }
1780
1781   return exceed;
1782 }
1783
1784 /*+
1785  *
1786  * Routine Description:
1787  *   Handles and analysis incoming beacon frames.
1788  *
1789  *
1790  * Return Value:
1791  *    None.
1792  *
1793 -*/
1794
1795 static
1796 void
1797 s_vMgrRxBeacon(
1798      PSDevice pDevice,
1799      PSMgmtObject pMgmt,
1800      PSRxMgmtPacket pRxPacket,
1801      BOOL bInScan
1802     )
1803 {
1804
1805     PKnownBSS           pBSSList;
1806     WLAN_FR_BEACON      sFrame;
1807     QWORD               qwTSFOffset;
1808     BOOL                bIsBSSIDEqual = FALSE;
1809     BOOL                bIsSSIDEqual = FALSE;
1810     BOOL                bTSFLargeDiff = FALSE;
1811     BOOL                bTSFOffsetPostive = FALSE;
1812     BOOL                bUpdateTSF = FALSE;
1813     BOOL                bIsAPBeacon = FALSE;
1814     BOOL                bIsChannelEqual = FALSE;
1815     unsigned int                uLocateByteIndex;
1816     BYTE                byTIMBitOn = 0;
1817     WORD                wAIDNumber = 0;
1818     unsigned int                uNodeIndex;
1819     QWORD               qwTimestamp, qwLocalTSF;
1820     QWORD               qwCurrTSF;
1821     WORD                wStartIndex = 0;
1822     WORD                wAIDIndex = 0;
1823     BYTE                byCurrChannel = pRxPacket->byRxChannel;
1824     ERPObject           sERP;
1825     unsigned int                uRateLen = WLAN_RATES_MAXLEN;
1826     BOOL                bChannelHit = FALSE;
1827     BYTE                byOldPreambleType;
1828
1829
1830
1831      if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
1832         return;
1833
1834     memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
1835     sFrame.len = pRxPacket->cbMPDULen;
1836     sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
1837
1838     // decode the beacon frame
1839     vMgrDecodeBeacon(&sFrame);
1840
1841     if ((sFrame.pwBeaconInterval == NULL)
1842         || (sFrame.pwCapInfo == NULL)
1843         || (sFrame.pSSID == NULL)
1844         || (sFrame.pSuppRates == NULL)) {
1845
1846         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
1847         return;
1848     }
1849
1850     if( byCurrChannel > CB_MAX_CHANNEL_24G )
1851     {
1852         if (sFrame.pDSParms != NULL) {
1853             if (byCurrChannel == RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
1854                 bChannelHit = TRUE;
1855             byCurrChannel = RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
1856         } else {
1857             bChannelHit = TRUE;
1858         }
1859
1860     } else {
1861         if (sFrame.pDSParms != NULL) {
1862             if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
1863                 bChannelHit = TRUE;
1864             byCurrChannel = sFrame.pDSParms->byCurrChannel;
1865         } else {
1866             bChannelHit = TRUE;
1867         }
1868     }
1869
1870 if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
1871       return;
1872
1873     if (sFrame.pERP != NULL) {
1874         sERP.byERP = sFrame.pERP->byContext;
1875         sERP.bERPExist = TRUE;
1876
1877     } else {
1878         sERP.bERPExist = FALSE;
1879         sERP.byERP = 0;
1880     }
1881
1882     pBSSList = BSSpAddrIsInBSSList((void *) pDevice,
1883                                    sFrame.pHdr->sA3.abyAddr3,
1884                                    sFrame.pSSID);
1885     if (pBSSList == NULL) {
1886         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon/insert: RxChannel = : %d\n", byCurrChannel);
1887         BSSbInsertToBSSList((void *) pDevice,
1888                             sFrame.pHdr->sA3.abyAddr3,
1889                             *sFrame.pqwTimestamp,
1890                             *sFrame.pwBeaconInterval,
1891                             *sFrame.pwCapInfo,
1892                             byCurrChannel,
1893                             sFrame.pSSID,
1894                             sFrame.pSuppRates,
1895                             sFrame.pExtSuppRates,
1896                             &sERP,
1897                             sFrame.pRSN,
1898                             sFrame.pRSNWPA,
1899                             sFrame.pIE_Country,
1900                             sFrame.pIE_Quiet,
1901                             sFrame.len - WLAN_HDR_ADDR3_LEN,
1902                             sFrame.pHdr->sA4.abyAddr4,   // payload of beacon
1903                             (void *) pRxPacket);
1904     }
1905     else {
1906 //        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"update bcn: RxChannel = : %d\n", byCurrChannel);
1907         BSSbUpdateToBSSList((void *) pDevice,
1908                             *sFrame.pqwTimestamp,
1909                             *sFrame.pwBeaconInterval,
1910                             *sFrame.pwCapInfo,
1911                             byCurrChannel,
1912                             bChannelHit,
1913                             sFrame.pSSID,
1914                             sFrame.pSuppRates,
1915                             sFrame.pExtSuppRates,
1916                             &sERP,
1917                             sFrame.pRSN,
1918                             sFrame.pRSNWPA,
1919                             sFrame.pIE_Country,
1920                             sFrame.pIE_Quiet,
1921                             pBSSList,
1922                             sFrame.len - WLAN_HDR_ADDR3_LEN,
1923                             sFrame.pHdr->sA4.abyAddr4,   // payload of probresponse
1924                             (void *) pRxPacket);
1925
1926     }
1927
1928     if (bInScan) {
1929         return;
1930     }
1931
1932     if(byCurrChannel == (BYTE)pMgmt->uCurrChannel)
1933        bIsChannelEqual = TRUE;
1934
1935     if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
1936
1937         // if rx beacon without ERP field
1938         if (sERP.bERPExist) {
1939             if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)){
1940                 pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1941                 pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
1942             }
1943         }
1944         else {
1945             pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1946             pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
1947         }
1948
1949         if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
1950             if(!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
1951                 pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
1952             if(!sERP.bERPExist)
1953                 pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
1954         }
1955     }
1956
1957     // check if BSSID the same
1958     if (memcmp(sFrame.pHdr->sA3.abyAddr3,
1959                pMgmt->abyCurrBSSID,
1960                WLAN_BSSID_LEN) == 0) {
1961
1962         bIsBSSIDEqual = TRUE;
1963         pDevice->uCurrRSSI = pRxPacket->uRSSI;
1964         pDevice->byCurrSQ = pRxPacket->bySQ;
1965         if (pMgmt->sNodeDBTable[0].uInActiveCount != 0) {
1966             pMgmt->sNodeDBTable[0].uInActiveCount = 0;
1967             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"BCN:Wake Count= [%d]\n", pMgmt->wCountToWakeUp);
1968         }
1969     }
1970     // check if SSID the same
1971     if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
1972         if (memcmp(sFrame.pSSID->abySSID,
1973                    ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
1974                    sFrame.pSSID->len
1975                    ) == 0) {
1976             bIsSSIDEqual = TRUE;
1977         }
1978     }
1979
1980     if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== TRUE) &&
1981         (bIsBSSIDEqual == TRUE) &&
1982         (bIsSSIDEqual == TRUE) &&
1983         (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
1984         (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
1985         // add state check to prevent reconnect fail since we'll receive Beacon
1986
1987         bIsAPBeacon = TRUE;
1988         if (pBSSList != NULL) {
1989
1990                 // Sync ERP field
1991                 if ((pBSSList->sERP.bERPExist == TRUE) && (pDevice->byBBType == BB_TYPE_11G)) {
1992                     if ((pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
1993                         pDevice->bProtectMode = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
1994                         if (pDevice->bProtectMode) {
1995                             MACvEnableProtectMD(pDevice);
1996                         } else {
1997                             MACvDisableProtectMD(pDevice);
1998                         }
1999                         vUpdateIFS(pDevice);
2000                     }
2001                     if ((pBSSList->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
2002                         pDevice->bNonERPPresent = (pBSSList->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
2003                     }
2004                     if ((pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
2005                         pDevice->bBarkerPreambleMd = (pBSSList->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
2006                         //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
2007                         if (pDevice->bBarkerPreambleMd) {
2008                             MACvEnableBarkerPreambleMd(pDevice);
2009                         } else {
2010                             MACvDisableBarkerPreambleMd(pDevice);
2011                         }
2012                     }
2013                 }
2014                 // Sync Short Slot Time
2015                 if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo) != pDevice->bShortSlotTime) {
2016                     BOOL    bShortSlotTime;
2017
2018                     bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pBSSList->wCapInfo);
2019                     //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
2020                     //Kyle check if it is OK to set G.
2021                     if (pDevice->byBBType == BB_TYPE_11A) {
2022                         bShortSlotTime = TRUE;
2023                     }
2024                     else if (pDevice->byBBType == BB_TYPE_11B) {
2025                         bShortSlotTime = FALSE;
2026                     }
2027                     if (bShortSlotTime != pDevice->bShortSlotTime) {
2028                         pDevice->bShortSlotTime = bShortSlotTime;
2029                         BBvSetShortSlotTime(pDevice);
2030                         vUpdateIFS(pDevice);
2031                     }
2032                 }
2033
2034                 //
2035                 // Preamble may change dynamiclly
2036                 //
2037                 byOldPreambleType = pDevice->byPreambleType;
2038                 if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pBSSList->wCapInfo)) {
2039                     pDevice->byPreambleType = pDevice->byShortPreamble;
2040                 }
2041                 else {
2042                     pDevice->byPreambleType = 0;
2043                 }
2044                 if (pDevice->byPreambleType != byOldPreambleType)
2045                     CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
2046             //
2047             // Basic Rate Set may change dynamiclly
2048             //
2049             if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B) {
2050                 uRateLen = WLAN_RATES_MAXLEN_11B;
2051             }
2052             pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
2053                                                     (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2054                                                     uRateLen);
2055             pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
2056                                                     (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
2057                                                     uRateLen);
2058             RATEvParseMaxRate((void *)pDevice,
2059                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2060                                (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
2061                                TRUE,
2062                                &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
2063                                &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
2064                                &(pMgmt->sNodeDBTable[0].wSuppRate),
2065                                &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
2066                                &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
2067                               );
2068
2069         }
2070     }
2071
2072 //    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Beacon 2 \n");
2073     // check if CF field exisit
2074     if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
2075         if (sFrame.pCFParms->wCFPDurRemaining > 0) {
2076             // TODO: deal with CFP period to set NAV
2077         }
2078     }
2079
2080     HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
2081     LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
2082     HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF);
2083     LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF);
2084
2085     // check if beacon TSF larger or small than our local TSF
2086     if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
2087         if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) {
2088             bTSFOffsetPostive = TRUE;
2089         }
2090         else {
2091             bTSFOffsetPostive = FALSE;
2092         }
2093     }
2094     else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
2095         bTSFOffsetPostive = TRUE;
2096     }
2097     else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
2098         bTSFOffsetPostive = FALSE;
2099     }
2100
2101     if (bTSFOffsetPostive) {
2102         qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
2103     }
2104     else {
2105         qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
2106     }
2107
2108     if (HIDWORD(qwTSFOffset) != 0 ||
2109         (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE )) {
2110          bTSFLargeDiff = TRUE;
2111     }
2112
2113
2114     // if infra mode
2115     if (bIsAPBeacon == TRUE) {
2116
2117         // Infra mode: Local TSF always follow AP's TSF if Difference huge.
2118         if (bTSFLargeDiff)
2119             bUpdateTSF = TRUE;
2120
2121         if ((pDevice->bEnablePSMode == TRUE) && (sFrame.pTIM)) {
2122
2123                 /* deal with DTIM, analysis TIM */
2124             pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? TRUE : FALSE ;
2125             pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
2126             pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
2127             wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
2128
2129             // check if AID in TIM field bit on
2130             // wStartIndex = N1
2131             wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
2132             // AIDIndex = N2
2133             wAIDIndex = (wAIDNumber >> 3);
2134             if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
2135                 uLocateByteIndex = wAIDIndex - wStartIndex;
2136                 // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
2137                 if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
2138                     byTIMBitOn  = (0x01) << ((wAIDNumber) % 8);
2139                     pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? TRUE : FALSE;
2140                 }
2141                 else {
2142                     pMgmt->bInTIM = FALSE;
2143                 };
2144             }
2145             else {
2146                 pMgmt->bInTIM = FALSE;
2147             };
2148
2149             if (pMgmt->bInTIM ||
2150                 (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
2151                 pMgmt->bInTIMWake = TRUE;
2152                 // send out ps-poll packet
2153 //                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:In TIM\n");
2154                 if (pMgmt->bInTIM) {
2155                     PSvSendPSPOLL((PSDevice)pDevice);
2156 //                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
2157                 }
2158
2159             }
2160             else {
2161                 pMgmt->bInTIMWake = FALSE;
2162                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
2163                 if (pDevice->bPWBitOn == FALSE) {
2164                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
2165                     if (PSbSendNullPacket(pDevice))
2166                         pDevice->bPWBitOn = TRUE;
2167                 }
2168                 if(PSbConsiderPowerDown(pDevice, FALSE, FALSE)) {
2169                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
2170                 }
2171             }
2172
2173         }
2174
2175     }
2176     // if adhoc mode
2177     if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
2178         if (bIsBSSIDEqual) {
2179             // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
2180                     if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
2181                             pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2182
2183             // adhoc mode:TSF updated only when beacon larger then local TSF
2184             if (bTSFLargeDiff && bTSFOffsetPostive &&
2185                 (pMgmt->eCurrState == WMAC_STATE_JOINTED))
2186                 bUpdateTSF = TRUE;
2187
2188             // During dpc, already in spinlocked.
2189             if (BSSbIsSTAInNodeDB(pDevice, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
2190
2191                 // Update the STA, (Techically the Beacons of all the IBSS nodes
2192                         // should be identical, but that's not happening in practice.
2193                 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2194                                                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2195                                                         WLAN_RATES_MAXLEN_11B);
2196                 RATEvParseMaxRate((void *)pDevice,
2197                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2198                                    NULL,
2199                                    TRUE,
2200                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2201                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2202                                    &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2203                                    &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2204                                    &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2205                                   );
2206                 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2207                 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2208                 pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
2209             }
2210             else {
2211                 // Todo, initial Node content
2212                 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
2213
2214                 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2215                                                         (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2216                                                         WLAN_RATES_MAXLEN_11B);
2217                 RATEvParseMaxRate((void *)pDevice,
2218                                    (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2219                                    NULL,
2220                                    TRUE,
2221                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2222                                    &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2223                                    &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2224                                    &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2225                                    &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2226                                  );
2227
2228                 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
2229                 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2230                 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
2231 /*
2232                 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2233                 if(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
2234                        pMgmt->sNodeDBTable[uNodeIndex].bERPExist = TRUE;
2235 */
2236             }
2237
2238             // if other stations jointed, indicate connect to upper layer..
2239             if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
2240                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
2241                 pMgmt->eCurrState = WMAC_STATE_JOINTED;
2242                 pDevice->bLinkPass = TRUE;
2243                 ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
2244                 if (netif_queue_stopped(pDevice->dev)){
2245                     netif_wake_queue(pDevice->dev);
2246                 }
2247                 pMgmt->sNodeDBTable[0].bActive = TRUE;
2248                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2249
2250             }
2251         }
2252         else if (bIsSSIDEqual) {
2253
2254             // See other adhoc sta with the same SSID but BSSID is different.
2255             // adpot this vars only when TSF larger then us.
2256             if (bTSFLargeDiff && bTSFOffsetPostive) {
2257                  // we don't support ATIM under adhoc mode
2258                // if ( sFrame.pIBSSParms->wATIMWindow == 0) {
2259                      // adpot this vars
2260                      // TODO: check sFrame cap if privacy on, and support rate syn
2261                      memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
2262                      memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
2263                      pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
2264                      pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
2265                      pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2266                                                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2267                                                       WLAN_RATES_MAXLEN_11B);
2268                      // set HW beacon interval and re-synchronizing....
2269                      DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
2270
2271                      MACvWriteBeaconInterval(pDevice, pMgmt->wCurrBeaconPeriod);
2272                      CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
2273                      CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2274
2275                      // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
2276                      MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
2277
2278                     byOldPreambleType = pDevice->byPreambleType;
2279                     if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo)) {
2280                         pDevice->byPreambleType = pDevice->byShortPreamble;
2281                     }
2282                     else {
2283                         pDevice->byPreambleType = 0;
2284                     }
2285                     if (pDevice->byPreambleType != byOldPreambleType)
2286                         CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
2287
2288
2289                      // MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID);
2290                      // set highest basic rate
2291                      // s_vSetHighestBasicRate(pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates);
2292                      // Prepare beacon frame
2293                         bMgrPrepareBeaconToSend((void *) pDevice, pMgmt);
2294               //  }
2295             }
2296         }
2297     }
2298     // endian issue ???
2299     // Update TSF
2300     if (bUpdateTSF) {
2301         CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
2302         CARDvAdjustTSF(pDevice, pRxPacket->byRxRate, qwTimestamp , pRxPacket->qwLocalTSF);
2303         CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
2304         CARDvUpdateNextTBTT(pDevice, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2305     }
2306
2307     return;
2308 }
2309
2310 /*+
2311  *
2312  * Routine Description:
2313  *   Instructs the hw to create a bss using the supplied
2314  *   attributes. Note that this implementation only supports Ad-Hoc
2315  *   BSS creation.
2316  *
2317  *
2318  * Return Value:
2319  *    CMD_STATUS
2320  *
2321 -*/
2322
2323 void vMgrCreateOwnIBSS(void *hDeviceContext,
2324                        PCMD_STATUS pStatus)
2325 {
2326     PSDevice            pDevice = (PSDevice)hDeviceContext;
2327     PSMgmtObject        pMgmt = &(pDevice->sMgmtObj);
2328     WORD                wMaxBasicRate;
2329     WORD                wMaxSuppRate;
2330     BYTE                byTopCCKBasicRate;
2331     BYTE                byTopOFDMBasicRate;
2332     QWORD               qwCurrTSF;
2333     unsigned int                ii;
2334     BYTE    abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
2335     BYTE    abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
2336     BYTE    abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2337     WORD                wSuppRate;
2338
2339
2340
2341     HIDWORD(qwCurrTSF) = 0;
2342     LODWORD(qwCurrTSF) = 0;
2343
2344     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
2345
2346     if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2347         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
2348             (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
2349             (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
2350             // encryption mode error
2351             *pStatus = CMD_STATUS_FAILURE;
2352             return;
2353         }
2354     }
2355
2356     pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2357     pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
2358
2359     if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2360         pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
2361     } else {
2362         if (pDevice->byBBType == BB_TYPE_11G)
2363             pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
2364         if (pDevice->byBBType == BB_TYPE_11B)
2365             pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
2366         if (pDevice->byBBType == BB_TYPE_11A)
2367             pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
2368     }
2369
2370     if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
2371         pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
2372         pMgmt->abyCurrExtSuppRates[1] = 0;
2373         for (ii = 0; ii < 4; ii++)
2374             pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2375     } else {
2376         pMgmt->abyCurrSuppRates[1] = 8;
2377         pMgmt->abyCurrExtSuppRates[1] = 0;
2378         for (ii = 0; ii < 8; ii++)
2379             pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2380     }
2381
2382
2383     if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
2384         pMgmt->abyCurrSuppRates[1] = 8;
2385         pMgmt->abyCurrExtSuppRates[1] = 4;
2386         for (ii = 0; ii < 4; ii++)
2387             pMgmt->abyCurrSuppRates[2+ii] =  abyCCK_RATE[ii];
2388         for (ii = 4; ii < 8; ii++)
2389             pMgmt->abyCurrSuppRates[2+ii] =  abyOFDM_RATE[ii-4];
2390         for (ii = 0; ii < 4; ii++)
2391             pMgmt->abyCurrExtSuppRates[2+ii] =  abyOFDM_RATE[ii+4];
2392     }
2393
2394
2395     // Disable Protect Mode
2396     pDevice->bProtectMode = 0;
2397     MACvDisableProtectMD(pDevice);
2398
2399     pDevice->bBarkerPreambleMd = 0;
2400     MACvDisableBarkerPreambleMd(pDevice);
2401
2402     // Kyle Test 2003.11.04
2403
2404     // set HW beacon interval
2405     if (pMgmt->wIBSSBeaconPeriod == 0)
2406         pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
2407     MACvWriteBeaconInterval(pDevice, pMgmt->wIBSSBeaconPeriod);
2408
2409     CARDbGetCurrentTSF(pDevice, &qwCurrTSF);
2410     // clear TSF counter
2411     CARDbClearCurrentTSF(pDevice);
2412
2413     // enable TSF counter
2414     MACvRegBitsOn(pDevice,MAC_REG_TFTCTL,TFTCTL_TSFCNTREN);
2415     // set Next TBTT
2416     CARDvSetFirstNextTBTT(pDevice, pMgmt->wIBSSBeaconPeriod);
2417
2418     pMgmt->uIBSSChannel = pDevice->uChannel;
2419
2420     if (pMgmt->uIBSSChannel == 0)
2421         pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
2422
2423     // set channel and clear NAV
2424     CARDbSetMediaChannel(pDevice, pMgmt->uIBSSChannel);
2425     pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2426
2427     pDevice->byPreambleType = pDevice->byShortPreamble;
2428
2429     // set basic rate
2430
2431     RATEvParseMaxRate((void *)pDevice,
2432                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2433                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, TRUE,
2434                       &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2435                       &byTopCCKBasicRate, &byTopOFDMBasicRate);
2436
2437
2438
2439     if (pDevice->byBBType == BB_TYPE_11A) {
2440         pDevice->bShortSlotTime = TRUE;
2441     } else {
2442         pDevice->bShortSlotTime = FALSE;
2443     }
2444     BBvSetShortSlotTime(pDevice);
2445     // vUpdateIFS() use pDevice->bShortSlotTime as parameter so it must be called
2446     // after setting ShortSlotTime.
2447     // CARDvSetBSSMode call vUpdateIFS()
2448     CARDvSetBSSMode(pDevice);
2449
2450     if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2451         MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_AP);
2452         pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
2453     }
2454
2455     if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2456         MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
2457         pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2458     }
2459
2460     // Adopt pre-configured IBSS vars to current vars
2461     pMgmt->eCurrState = WMAC_STATE_STARTED;
2462     pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
2463     pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2464     pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
2465     pDevice->uCurrRSSI = 0;
2466     pDevice->byCurrSQ = 0;
2467
2468     memcpy(pMgmt->abyDesireSSID,pMgmt->abyAdHocSSID,
2469                       ((PWLAN_IE_SSID)pMgmt->abyAdHocSSID)->len + WLAN_IEHDR_LEN);
2470
2471     memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2472     memcpy(pMgmt->abyCurrSSID,
2473            pMgmt->abyDesireSSID,
2474            ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
2475           );
2476
2477     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2478         // AP mode BSSID = MAC addr
2479         memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
2480         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n",
2481                       pMgmt->abyCurrBSSID[0],
2482                       pMgmt->abyCurrBSSID[1],
2483                       pMgmt->abyCurrBSSID[2],
2484                       pMgmt->abyCurrBSSID[3],
2485                       pMgmt->abyCurrBSSID[4],
2486                       pMgmt->abyCurrBSSID[5]
2487                     );
2488     }
2489
2490     if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2491
2492         // BSSID selected must be randomized as spec 11.1.3
2493         pMgmt->abyCurrBSSID[5] = (BYTE) (LODWORD(qwCurrTSF)& 0x000000ff);
2494         pMgmt->abyCurrBSSID[4] = (BYTE)((LODWORD(qwCurrTSF)& 0x0000ff00) >> 8);
2495         pMgmt->abyCurrBSSID[3] = (BYTE)((LODWORD(qwCurrTSF)& 0x00ff0000) >> 16);
2496         pMgmt->abyCurrBSSID[2] = (BYTE)((LODWORD(qwCurrTSF)& 0x00000ff0) >> 4);
2497         pMgmt->abyCurrBSSID[1] = (BYTE)((LODWORD(qwCurrTSF)& 0x000ff000) >> 12);
2498         pMgmt->abyCurrBSSID[0] = (BYTE)((LODWORD(qwCurrTSF)& 0x0ff00000) >> 20);
2499         pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
2500         pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
2501         pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
2502         pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
2503         pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
2504         pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
2505         pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
2506         pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
2507
2508
2509         DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n",
2510                       pMgmt->abyCurrBSSID[0],
2511                       pMgmt->abyCurrBSSID[1],
2512                       pMgmt->abyCurrBSSID[2],
2513                       pMgmt->abyCurrBSSID[3],
2514                       pMgmt->abyCurrBSSID[4],
2515                       pMgmt->abyCurrBSSID[5]
2516                     );
2517     }
2518
2519     // set BSSID filter
2520     MACvWriteBSSIDAddress(pDevice, pMgmt->abyCurrBSSID);
2521     memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
2522
2523     MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
2524     pDevice->byRxMode |= RCR_BSSID;
2525     pMgmt->bCurrBSSIDFilterOn = TRUE;
2526
2527     // Set Capability Info
2528     pMgmt->wCurrCapInfo = 0;
2529
2530     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2531         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
2532         pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
2533         pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2534         pDevice->eOPMode = OP_MODE_AP;
2535     }
2536
2537     if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2538         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
2539         pDevice->eOPMode = OP_MODE_ADHOC;
2540     }
2541
2542     if (pDevice->bEncryptionEnable) {
2543         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
2544         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2545             if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2546                 pMgmt->byCSSPK = KEY_CTL_CCMP;
2547                 pMgmt->byCSSGK = KEY_CTL_CCMP;
2548             } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2549                 pMgmt->byCSSPK = KEY_CTL_TKIP;
2550                 pMgmt->byCSSGK = KEY_CTL_TKIP;
2551             } else {
2552                 pMgmt->byCSSPK = KEY_CTL_NONE;
2553                 pMgmt->byCSSGK = KEY_CTL_WEP;
2554             }
2555         } else {
2556             pMgmt->byCSSPK = KEY_CTL_WEP;
2557             pMgmt->byCSSGK = KEY_CTL_WEP;
2558         }
2559     }
2560
2561     pMgmt->byERPContext = 0;
2562
2563     if (pDevice->byPreambleType == 1) {
2564         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
2565     } else {
2566         pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
2567     }
2568
2569     pMgmt->eCurrState = WMAC_STATE_STARTED;
2570     // Prepare beacon to send
2571     if (bMgrPrepareBeaconToSend((void *) pDevice, pMgmt))
2572         *pStatus = CMD_STATUS_SUCCESS;
2573
2574     return;
2575 }
2576
2577 /*+
2578  *
2579  * Routine Description:
2580  *   Instructs wmac to join a bss using the supplied attributes.
2581  *   The arguments may the BSSID or SSID and the rest of the
2582  *   attributes are obtained from the scan result of known bss list.
2583  *
2584  *
2585  * Return Value:
2586  *    None.
2587  *
2588 -*/
2589
2590 void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus)
2591 {
2592     PSDevice     pDevice = (PSDevice)hDeviceContext;
2593     PSMgmtObject    pMgmt = &(pDevice->sMgmtObj);
2594     PKnownBSS       pCurr = NULL;
2595     unsigned int            ii, uu;
2596     PWLAN_IE_SUPP_RATES pItemRates = NULL;
2597     PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
2598     PWLAN_IE_SSID   pItemSSID;
2599     unsigned int            uRateLen = WLAN_RATES_MAXLEN;
2600     WORD            wMaxBasicRate = RATE_1M;
2601     WORD            wMaxSuppRate = RATE_1M;
2602     WORD            wSuppRate;
2603     BYTE            byTopCCKBasicRate = RATE_1M;
2604     BYTE            byTopOFDMBasicRate = RATE_1M;
2605     BOOL            bShortSlotTime = FALSE;
2606
2607
2608     for (ii = 0; ii < MAX_BSS_NUM; ii++) {
2609         if (pMgmt->sBSSList[ii].bActive == TRUE)
2610             break;
2611     }
2612
2613     if (ii == MAX_BSS_NUM) {
2614        *pStatus = CMD_STATUS_RESOURCES;
2615         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
2616        return;
2617     }
2618
2619     // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
2620     // Search known BSS list for prefer BSSID or SSID
2621
2622     pCurr = BSSpSearchBSSList(pDevice,
2623                               pMgmt->abyDesireBSSID,
2624                               pMgmt->abyDesireSSID,
2625                               pDevice->eConfigPHYMode
2626                               );
2627
2628     if (pCurr == NULL){
2629        *pStatus = CMD_STATUS_RESOURCES;
2630        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
2631        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
2632        return;
2633     }
2634
2635     DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
2636
2637     if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
2638
2639         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
2640             (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
2641                 /*
2642             if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2643                 if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
2644                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
2645                     // encryption mode error
2646                     pMgmt->eCurrState = WMAC_STATE_IDLE;
2647                     return;
2648                 }
2649             } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2650                 if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
2651                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"No match RSN info. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
2652                     // encryption mode error
2653                     pMgmt->eCurrState = WMAC_STATE_IDLE;
2654                     return;
2655                 }
2656             }
2657 */
2658         }
2659
2660 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2661         //if(pDevice->bWPASuppWextEnabled == TRUE)
2662             Encyption_Rebuild(pDevice, pCurr);
2663 #endif
2664
2665         // Infrastructure BSS
2666         s_vMgrSynchBSS(pDevice,
2667                        WMAC_MODE_ESS_STA,
2668                        pCurr,
2669                        pStatus
2670                        );
2671
2672         if (*pStatus == CMD_STATUS_SUCCESS){
2673
2674             // Adopt this BSS state vars in Mgmt Object
2675             pMgmt->uCurrChannel = pCurr->uChannel;
2676
2677             memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2678             memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2679
2680             if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
2681                 uRateLen = WLAN_RATES_MAXLEN_11B;
2682             }
2683
2684             pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
2685             pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
2686
2687             // Parse Support Rate IE
2688             pItemRates->byElementID = WLAN_EID_SUPP_RATES;
2689             pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2690                                          pItemRates,
2691                                          uRateLen);
2692
2693             // Parse Extension Support Rate IE
2694             pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
2695             pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
2696                                             pItemExtRates,
2697                                             uRateLen);
2698             // Stuffing Rate IE
2699             if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
2700                 for (ii = 0; ii < (unsigned int) (8 - pItemRates->len); ) {
2701                         pItemRates->abyRates[pItemRates->len + ii] =
2702                                 pItemExtRates->abyRates[ii];
2703                         ii++;
2704                     if (pItemExtRates->len <= ii)
2705                         break;
2706                 }
2707                 pItemRates->len += (BYTE)ii;
2708                 if (pItemExtRates->len - ii > 0) {
2709                     pItemExtRates->len -= (BYTE)ii;
2710                     for (uu = 0; uu < pItemExtRates->len; uu ++) {
2711                         pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
2712                     }
2713                 } else {
2714                     pItemExtRates->len = 0;
2715                 }
2716             }
2717
2718             RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, TRUE,
2719                               &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2720                               &byTopCCKBasicRate, &byTopOFDMBasicRate);
2721             vUpdateIFS(pDevice);
2722             // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
2723             // TODO: deal with if wCapInfo the PS-Pollable is on.
2724             pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2725             memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2726             memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2727             memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2728
2729             pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
2730
2731             pMgmt->eCurrState = WMAC_STATE_JOINTED;
2732             // Adopt BSS state in Adapter Device Object
2733             pDevice->eOPMode = OP_MODE_INFRASTRUCTURE;
2734             memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2735
2736             // Add current BSS to Candidate list
2737             // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
2738             if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
2739                 BOOL bResult = bAdd_PMKID_Candidate((void *) pDevice,
2740                                                     pMgmt->abyCurrBSSID,
2741                                                     &pCurr->sRSNCapObj);
2742                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate: 1(%d)\n", bResult);
2743                 if (bResult == FALSE) {
2744                         vFlush_PMKID_Candidate((void *) pDevice);
2745                         DBG_PRT(MSG_LEVEL_DEBUG,
2746                                 KERN_INFO "vFlush_PMKID_Candidate: 4\n");
2747                         bAdd_PMKID_Candidate((void *) pDevice,
2748                                              pMgmt->abyCurrBSSID,
2749                                              &pCurr->sRSNCapObj);
2750                 }
2751             }
2752
2753             // Preamble type auto-switch: if AP can receive short-preamble cap,
2754             // we can turn on too.
2755             if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
2756                 pDevice->byPreambleType = pDevice->byShortPreamble;
2757             }
2758             else {
2759                 pDevice->byPreambleType = 0;
2760             }
2761             // Change PreambleType must set RSPINF again
2762             CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
2763
2764             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join ESS\n");
2765
2766             if (pCurr->eNetworkTypeInUse == PHY_TYPE_11G) {
2767
2768                 if ((pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION) != pDevice->bProtectMode) {//0000 0010
2769                     pDevice->bProtectMode = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
2770                     if (pDevice->bProtectMode) {
2771                         MACvEnableProtectMD(pDevice);
2772                     } else {
2773                         MACvDisableProtectMD(pDevice);
2774                     }
2775                     vUpdateIFS(pDevice);
2776                 }
2777                 if ((pCurr->sERP.byERP & WLAN_EID_ERP_NONERP_PRESENT) != pDevice->bNonERPPresent) {//0000 0001
2778                     pDevice->bNonERPPresent = (pCurr->sERP.byERP & WLAN_EID_ERP_USE_PROTECTION);
2779                 }
2780                 if ((pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE) != pDevice->bBarkerPreambleMd) {//0000 0100
2781                     pDevice->bBarkerPreambleMd = (pCurr->sERP.byERP & WLAN_EID_ERP_BARKER_MODE);
2782                     //BarkerPreambleMd has higher priority than shortPreamble bit in Cap
2783                     if (pDevice->bBarkerPreambleMd) {
2784                         MACvEnableBarkerPreambleMd(pDevice);
2785                     } else {
2786                         MACvDisableBarkerPreambleMd(pDevice);
2787                     }
2788                 }
2789             }
2790             //DBG_PRN_WLAN05(("wCapInfo: %X\n", pCurr->wCapInfo));
2791             if (WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo) != pDevice->bShortSlotTime) {
2792                 if (pDevice->byBBType == BB_TYPE_11A) {
2793                     bShortSlotTime = TRUE;
2794                 }
2795                 else if (pDevice->byBBType == BB_TYPE_11B) {
2796                     bShortSlotTime = FALSE;
2797                 }
2798                 else {
2799                     bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(pCurr->wCapInfo);
2800                 }
2801                 //DBG_PRN_WLAN05(("Set Short Slot Time: %d\n", pDevice->bShortSlotTime));
2802                 if (bShortSlotTime != pDevice->bShortSlotTime) {
2803                     pDevice->bShortSlotTime = bShortSlotTime;
2804                     BBvSetShortSlotTime(pDevice);
2805                     vUpdateIFS(pDevice);
2806                 }
2807             }
2808
2809             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"End of Join AP -- A/B/G Action\n");
2810         }
2811         else {
2812             pMgmt->eCurrState = WMAC_STATE_IDLE;
2813         };
2814
2815
2816      }
2817      else {
2818         // ad-hoc mode BSS
2819         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2820
2821             if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2822 /*
2823                 if (WPA_SearchRSN(0, WPA_TKIP, pCurr) == FALSE) {
2824                     // encryption mode error
2825                     pMgmt->eCurrState = WMAC_STATE_IDLE;
2826                     return;
2827                 }
2828 */
2829             } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2830 /*
2831                 if (WPA_SearchRSN(0, WPA_AESCCMP, pCurr) == FALSE) {
2832                     // encryption mode error
2833                     pMgmt->eCurrState = WMAC_STATE_IDLE;
2834                     return;
2835                 }
2836 */
2837             } else {
2838                 // encryption mode error
2839                 pMgmt->eCurrState = WMAC_STATE_IDLE;
2840                 return;
2841             }
2842         }
2843
2844         s_vMgrSynchBSS(pDevice,
2845                        WMAC_MODE_IBSS_STA,
2846                        pCurr,
2847                        pStatus
2848                        );
2849
2850         if (*pStatus == CMD_STATUS_SUCCESS){
2851             // Adopt this BSS state vars in Mgmt Object
2852             // TODO: check if CapInfo privacy on, but we don't..
2853             pMgmt->uCurrChannel = pCurr->uChannel;
2854
2855
2856             // Parse Support Rate IE
2857             pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2858             pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2859                                                     (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2860                                                     WLAN_RATES_MAXLEN_11B);
2861             // set basic rate
2862             RATEvParseMaxRate((void *)pDevice,
2863                               (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2864                               NULL, TRUE, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2865                               &byTopCCKBasicRate, &byTopOFDMBasicRate);
2866             vUpdateIFS(pDevice);
2867             pMgmt->wCurrCapInfo = pCurr->wCapInfo;
2868             pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2869             memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2870             memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2871             memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2872 //          pMgmt->wCurrATIMWindow = pCurr->wATIMWindow;
2873             pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2874             pMgmt->eCurrState = WMAC_STATE_STARTED;
2875             // Adopt BSS state in Adapter Device Object
2876             pDevice->eOPMode = OP_MODE_ADHOC;
2877             pDevice->bLinkPass = TRUE;
2878             ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER);
2879             memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2880
2881             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n",
2882                   pMgmt->abyCurrBSSID[0],
2883                   pMgmt->abyCurrBSSID[1],
2884                   pMgmt->abyCurrBSSID[2],
2885                   pMgmt->abyCurrBSSID[3],
2886                   pMgmt->abyCurrBSSID[4],
2887                   pMgmt->abyCurrBSSID[5]
2888                 );
2889             // Preamble type auto-switch: if AP can receive short-preamble cap,
2890             // and if registry setting is short preamble we can turn on too.
2891
2892             if (WLAN_GET_CAP_INFO_SHORTPREAMBLE(pCurr->wCapInfo)) {
2893                 pDevice->byPreambleType = pDevice->byShortPreamble;
2894             }
2895             else {
2896                 pDevice->byPreambleType = 0;
2897             }
2898             // Change PreambleType must set RSPINF again
2899             CARDvSetRSPINF(pDevice, (BYTE)pDevice->byBBType);
2900
2901             // Prepare beacon
2902                 bMgrPrepareBeaconToSend((void *) pDevice, pMgmt);
2903         }
2904         else {
2905             pMgmt->eCurrState = WMAC_STATE_IDLE;
2906         };
2907      };
2908     return;
2909 }
2910
2911
2912
2913 /*+
2914  *
2915  * Routine Description:
2916  * Set HW to synchronize a specific BSS from known BSS list.
2917  *
2918  *
2919  * Return Value:
2920  *    PCM_STATUS
2921  *
2922 -*/
2923 static
2924 void
2925 s_vMgrSynchBSS (
2926      PSDevice      pDevice,
2927      unsigned int          uBSSMode,
2928      PKnownBSS     pCurr,
2929      PCMD_STATUS  pStatus
2930     )
2931 {
2932     PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
2933                                                      //1M,   2M,   5M,   11M,  18M,  24M,  36M,  54M
2934     BYTE abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
2935     BYTE abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
2936                                                            //6M,   9M,   12M,  48M
2937     BYTE abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2938     BYTE abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
2939
2940
2941     *pStatus = CMD_STATUS_FAILURE;
2942
2943     if (s_bCipherMatch(pCurr,
2944                        pDevice->eEncryptionStatus,
2945                        &(pMgmt->byCSSPK),
2946                        &(pMgmt->byCSSGK)) == FALSE) {
2947         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "s_bCipherMatch Fail .......\n");
2948         return;
2949     }
2950
2951     pMgmt->pCurrBSS = pCurr;
2952
2953     // if previous mode is IBSS.
2954     if(pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2955         MACvRegBitsOff(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
2956     }
2957
2958     // Init the BSS informations
2959     pDevice->bCCK = TRUE;
2960     pDevice->bProtectMode = FALSE;
2961     MACvDisableProtectMD(pDevice);
2962     pDevice->bBarkerPreambleMd = FALSE;
2963     MACvDisableBarkerPreambleMd(pDevice);
2964     pDevice->bNonERPPresent = FALSE;
2965     pDevice->byPreambleType = 0;
2966     pDevice->wBasicRate = 0;
2967     // Set Basic Rate
2968     CARDbAddBasicRate((void *)pDevice, RATE_1M);
2969
2970     // calculate TSF offset
2971     // TSF Offset = Received Timestamp TSF - Marked Local's TSF
2972     CARDvAdjustTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
2973
2974     // set HW beacon interval
2975     MACvWriteBeaconInterval(pDevice, pCurr->wBeaconInterval);
2976
2977     // set Next TBTT
2978     // Next TBTT = ((local_current_TSF / beacon_interval) + 1 ) * beacon_interval
2979     CARDvSetFirstNextTBTT(pDevice, pCurr->wBeaconInterval);
2980
2981     // set BSSID
2982     MACvWriteBSSIDAddress(pDevice, pCurr->abyBSSID);
2983
2984     memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, 6);
2985
2986     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n",
2987         pMgmt->abyCurrBSSID[0],
2988         pMgmt->abyCurrBSSID[1],
2989         pMgmt->abyCurrBSSID[2],
2990         pMgmt->abyCurrBSSID[3],
2991         pMgmt->abyCurrBSSID[4],
2992         pMgmt->abyCurrBSSID[5]);
2993
2994     if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
2995         if ((pDevice->eConfigPHYMode == PHY_TYPE_11A) ||
2996             (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
2997             pDevice->byBBType = BB_TYPE_11A;
2998             pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
2999             pDevice->bShortSlotTime = TRUE;
3000             BBvSetShortSlotTime(pDevice);
3001             CARDvSetBSSMode(pDevice);
3002         } else {
3003             return;
3004         }
3005     } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
3006         if ((pDevice->eConfigPHYMode == PHY_TYPE_11B) ||
3007             (pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
3008             (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
3009             pDevice->byBBType = BB_TYPE_11B;
3010             pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
3011             pDevice->bShortSlotTime = FALSE;
3012             BBvSetShortSlotTime(pDevice);
3013             CARDvSetBSSMode(pDevice);
3014         } else {
3015             return;
3016         }
3017     } else {
3018         if ((pDevice->eConfigPHYMode == PHY_TYPE_11G) ||
3019             (pDevice->eConfigPHYMode == PHY_TYPE_AUTO)) {
3020             pDevice->byBBType = BB_TYPE_11G;
3021             pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
3022             pDevice->bShortSlotTime = TRUE;
3023             BBvSetShortSlotTime(pDevice);
3024             CARDvSetBSSMode(pDevice);
3025         } else if (pDevice->eConfigPHYMode == PHY_TYPE_11B) {
3026             pDevice->byBBType = BB_TYPE_11B;
3027             pDevice->bShortSlotTime = FALSE;
3028             BBvSetShortSlotTime(pDevice);
3029             CARDvSetBSSMode(pDevice);
3030         } else {
3031             return;
3032         }
3033     }
3034
3035     if (uBSSMode == WMAC_MODE_ESS_STA) {
3036         MACvRegBitsOff(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
3037         MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
3038         pDevice->byRxMode |= RCR_BSSID;
3039         pMgmt->bCurrBSSIDFilterOn = TRUE;
3040     }
3041
3042     // set channel and clear NAV
3043     CARDbSetMediaChannel(pDevice, pCurr->uChannel);
3044     pMgmt->uCurrChannel = pCurr->uChannel;
3045     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
3046
3047     if ((pDevice->bUpdateBBVGA) &&
3048         (pDevice->byBBVGACurrent != pDevice->abyBBVGA[0])) {
3049         pDevice->byBBVGACurrent = pDevice->abyBBVGA[0];
3050         BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent);
3051         BBvSetShortSlotTime(pDevice);
3052     }
3053     //
3054     // Notes:
3055     // 1. In Ad-hoc mode : check if received others beacon as jointed indication,
3056     //    otherwise we will start own IBSS.
3057     // 2. In Infra mode : Supposed we already synchronized with AP right now.
3058
3059     if (uBSSMode == WMAC_MODE_IBSS_STA) {
3060         MACvRegBitsOn(pDevice, MAC_REG_HOSTCR, HOSTCR_ADHOC);
3061         MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
3062         pDevice->byRxMode |= RCR_BSSID;
3063         pMgmt->bCurrBSSIDFilterOn = TRUE;
3064     }
3065
3066     if (pDevice->byBBType == BB_TYPE_11A) {
3067         memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
3068         pMgmt->abyCurrExtSuppRates[1] = 0;
3069     } else if (pDevice->byBBType == BB_TYPE_11B) {
3070         memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
3071         pMgmt->abyCurrExtSuppRates[1] = 0;
3072     } else {
3073         memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
3074         memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
3075     }
3076     pMgmt->byERPContext = pCurr->sERP.byERP;
3077
3078     *pStatus = CMD_STATUS_SUCCESS;
3079
3080     return;
3081 };
3082
3083
3084 //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption
3085 //                   ,need reset eAuthenMode and eEncryptionStatus
3086  static void  Encyption_Rebuild(
3087      PSDevice pDevice,
3088      PKnownBSS pCurr
3089  )
3090  {
3091   PSMgmtObject  pMgmt = &(pDevice->sMgmtObj);
3092   /* unsigned int ii, uSameBssidNum=0; */
3093
3094   //   if( uSameBssidNum>=2) {   //we only check AP in hidden sssid  mode
3095         if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||           //networkmanager 0.7.0 does not give the pairwise-key selsection,
3096              (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) {         // so we need re-selsect it according to real pairwise-key info.
3097                if(pCurr->bWPAValid == TRUE)  {   //WPA-PSK
3098                           pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
3099                     if(pCurr->abyPKType[0] == WPA_TKIP) {
3100                         pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;    //TKIP
3101                         PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
3102                       }
3103                    else if(pCurr->abyPKType[0] == WPA_AESCCMP) {
3104                         pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
3105                           PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
3106                      }
3107                 }
3108                else if(pCurr->bWPA2Valid == TRUE) {  //WPA2-PSK
3109                          pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
3110                        if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
3111                            pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled;     //TKIP
3112                              PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
3113                         }
3114                        else if(pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
3115                            pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled;    //AES
3116                             PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
3117                         }
3118                 }
3119               }
3120         //  }
3121       return;
3122  }
3123
3124
3125 /*+
3126  *
3127  * Routine Description:
3128  *  Format TIM field
3129  *
3130  *
3131  * Return Value:
3132  *    void
3133  *
3134 -*/
3135
3136 static
3137 void
3138 s_vMgrFormatTIM(
3139      PSMgmtObject pMgmt,
3140      PWLAN_IE_TIM pTIM
3141     )
3142 {
3143     BYTE        byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
3144     BYTE        byMap;
3145     unsigned int        ii, jj;
3146     BOOL        bStartFound = FALSE;
3147     BOOL        bMulticast = FALSE;
3148     WORD        wStartIndex = 0;
3149     WORD        wEndIndex = 0;
3150
3151
3152     // Find size of partial virtual bitmap
3153     for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
3154         byMap = pMgmt->abyPSTxMap[ii];
3155         if (!ii) {
3156             // Mask out the broadcast bit which is indicated separately.
3157             bMulticast = (byMap & byMask[0]) != 0;
3158             if(bMulticast) {
3159                pMgmt->sNodeDBTable[0].bRxPSPoll = TRUE;
3160             }
3161             byMap = 0;
3162         }
3163         if (byMap) {
3164             if (!bStartFound) {
3165                 bStartFound = TRUE;
3166                 wStartIndex = (WORD)ii;
3167             }
3168             wEndIndex = (WORD)ii;
3169         }
3170     }
3171
3172
3173     // Round start index down to nearest even number
3174     wStartIndex &=  ~BIT0;
3175
3176     // Round end index up to nearest even number
3177     wEndIndex = ((wEndIndex + 1) & ~BIT0);
3178
3179     // Size of element payload
3180
3181     pTIM->len =  3 + (wEndIndex - wStartIndex) + 1;
3182
3183     // Fill in the Fixed parts of the TIM
3184     pTIM->byDTIMCount = pMgmt->byDTIMCount;
3185     pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
3186     pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
3187         (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
3188
3189     // Append variable part of TIM
3190
3191     for (ii = wStartIndex, jj =0 ; ii <= wEndIndex; ii++, jj++) {
3192          pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
3193     }
3194
3195     // Aid = 0 don't used.
3196     pTIM->byVirtBitMap[0]  &= ~BIT0;
3197 }
3198
3199
3200 /*+
3201  *
3202  * Routine Description:
3203  *  Constructs an Beacon frame( Ad-hoc mode)
3204  *
3205  *
3206  * Return Value:
3207  *    PTR to frame; or NULL on allocation failue
3208  *
3209 -*/
3210
3211 static
3212 PSTxMgmtPacket
3213 s_MgrMakeBeacon(
3214      PSDevice pDevice,
3215      PSMgmtObject pMgmt,
3216      WORD wCurrCapInfo,
3217      WORD wCurrBeaconPeriod,
3218      unsigned int uCurrChannel,
3219      WORD wCurrATIMWinodw,
3220      PWLAN_IE_SSID pCurrSSID,
3221      PBYTE pCurrBSSID,
3222      PWLAN_IE_SUPP_RATES pCurrSuppRates,
3223      PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3224     )
3225 {
3226     PSTxMgmtPacket      pTxPacket = NULL;
3227     WLAN_FR_BEACON      sFrame;
3228     BYTE                abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
3229
3230
3231     // prepare beacon frame
3232     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3233     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
3234     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
3235     // Setup the sFrame structure.
3236     sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
3237     sFrame.len = WLAN_BEACON_FR_MAXLEN;
3238     vMgrEncodeBeacon(&sFrame);
3239     // Setup the header
3240     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3241         (
3242         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3243         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
3244         ));
3245
3246     if (pDevice->bEnablePSMode) {
3247         sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_PWRMGT(1));
3248     }
3249
3250     memcpy( sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
3251     memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3252     memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3253     *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3254     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3255     // Copy SSID
3256     sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3257     sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3258     memcpy(sFrame.pSSID,
3259              pCurrSSID,
3260              ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3261             );
3262     // Copy the rate set
3263     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3264     sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3265     memcpy(sFrame.pSuppRates,
3266            pCurrSuppRates,
3267            ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3268           );
3269     // DS parameter
3270     if (pDevice->byBBType != BB_TYPE_11A) {
3271         sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3272         sFrame.len += (1) + WLAN_IEHDR_LEN;
3273         sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3274         sFrame.pDSParms->len = 1;
3275         sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
3276     }
3277     // TIM field
3278     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
3279         sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
3280         sFrame.pTIM->byElementID = WLAN_EID_TIM;
3281         s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
3282         sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
3283     }
3284
3285     if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3286
3287         // IBSS parameter
3288         sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3289         sFrame.len += (2) + WLAN_IEHDR_LEN;
3290         sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3291         sFrame.pIBSSParms->len = 2;
3292         sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
3293         if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3294             /* RSN parameter */
3295             sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3296             sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3297             sFrame.pRSNWPA->len = 12;
3298             sFrame.pRSNWPA->abyOUI[0] = 0x00;
3299             sFrame.pRSNWPA->abyOUI[1] = 0x50;
3300             sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3301             sFrame.pRSNWPA->abyOUI[3] = 0x01;
3302             sFrame.pRSNWPA->wVersion = 1;
3303             sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3304             sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3305             sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3306             if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
3307                 sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
3308             else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
3309                 sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
3310             else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
3311                 sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
3312             else
3313                 sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
3314
3315             // Pairwise Key Cipher Suite
3316             sFrame.pRSNWPA->wPKCount = 0;
3317             // Auth Key Management Suite
3318             *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
3319             sFrame.pRSNWPA->len +=2;
3320
3321             // RSN Capabilites
3322             *((PWORD)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len))=0;
3323             sFrame.pRSNWPA->len +=2;
3324             sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3325         }
3326     }
3327
3328
3329     if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
3330         sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3331         sFrame.len += 1 + WLAN_IEHDR_LEN;
3332         sFrame.pERP->byElementID = WLAN_EID_ERP;
3333         sFrame.pERP->len = 1;
3334         sFrame.pERP->byContext = 0;
3335         if (pDevice->bProtectMode == TRUE)
3336             sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3337         if (pDevice->bNonERPPresent == TRUE)
3338             sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3339         if (pDevice->bBarkerPreambleMd == TRUE)
3340             sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3341     }
3342     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3343         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3344         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3345         memcpy(sFrame.pExtSuppRates,
3346              pCurrExtSuppRates,
3347              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3348              );
3349     }
3350     // hostapd wpa/wpa2 IE
3351     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
3352          if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3353              if (pMgmt->wWPAIELen != 0) {
3354                  sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3355                  memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3356                  sFrame.len += pMgmt->wWPAIELen;
3357              }
3358          }
3359     }
3360
3361     /* Adjust the length fields */
3362     pTxPacket->cbMPDULen = sFrame.len;
3363     pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3364
3365     return pTxPacket;
3366 }
3367
3368
3369
3370
3371
3372 /*+
3373  *
3374  * Routine Description:
3375  *  Constructs an Prob-response frame
3376  *
3377  *
3378  * Return Value:
3379  *    PTR to frame; or NULL on allocation failue
3380  *
3381 -*/
3382
3383
3384
3385
3386 PSTxMgmtPacket
3387 s_MgrMakeProbeResponse(
3388      PSDevice pDevice,
3389      PSMgmtObject pMgmt,
3390      WORD wCurrCapInfo,
3391      WORD wCurrBeaconPeriod,
3392      unsigned int uCurrChannel,
3393      WORD wCurrATIMWinodw,
3394      PBYTE pDstAddr,
3395      PWLAN_IE_SSID pCurrSSID,
3396      PBYTE pCurrBSSID,
3397      PWLAN_IE_SUPP_RATES pCurrSuppRates,
3398      PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
3399      BYTE byPHYType
3400     )
3401 {
3402     PSTxMgmtPacket      pTxPacket = NULL;
3403     WLAN_FR_PROBERESP   sFrame;
3404
3405
3406
3407     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3408     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
3409     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
3410     // Setup the sFrame structure.
3411     sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
3412     sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
3413     vMgrEncodeProbeResponse(&sFrame);
3414     // Setup the header
3415     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3416         (
3417         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3418         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
3419         ));
3420     memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3421     memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3422     memcpy( sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3423     *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3424     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3425
3426     if (byPHYType == BB_TYPE_11B) {
3427         *sFrame.pwCapInfo &= cpu_to_le16((WORD)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
3428     }
3429
3430     // Copy SSID
3431     sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3432     sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3433     memcpy(sFrame.pSSID,
3434            pCurrSSID,
3435            ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3436            );
3437     // Copy the rate set
3438     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3439
3440     sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3441     memcpy(sFrame.pSuppRates,
3442            pCurrSuppRates,
3443            ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3444           );
3445
3446     // DS parameter
3447     if (pDevice->byBBType != BB_TYPE_11A) {
3448         sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3449         sFrame.len += (1) + WLAN_IEHDR_LEN;
3450         sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3451         sFrame.pDSParms->len = 1;
3452         sFrame.pDSParms->byCurrChannel = (BYTE)uCurrChannel;
3453     }
3454
3455     if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3456         // IBSS parameter
3457         sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3458         sFrame.len += (2) + WLAN_IEHDR_LEN;
3459         sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3460         sFrame.pIBSSParms->len = 2;
3461         sFrame.pIBSSParms->wATIMWindow = 0;
3462     }
3463     if (pDevice->byBBType == BB_TYPE_11G) {
3464         sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3465         sFrame.len += 1 + WLAN_IEHDR_LEN;
3466         sFrame.pERP->byElementID = WLAN_EID_ERP;
3467         sFrame.pERP->len = 1;
3468         sFrame.pERP->byContext = 0;
3469         if (pDevice->bProtectMode == TRUE)
3470             sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3471         if (pDevice->bNonERPPresent == TRUE)
3472             sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3473         if (pDevice->bBarkerPreambleMd == TRUE)
3474             sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3475     }
3476
3477     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3478         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3479         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3480         memcpy(sFrame.pExtSuppRates,
3481              pCurrExtSuppRates,
3482              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3483              );
3484     }
3485
3486     // hostapd wpa/wpa2 IE
3487     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && (pDevice->bEnableHostapd == TRUE)) {
3488          if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3489              if (pMgmt->wWPAIELen != 0) {
3490                  sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3491                  memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3492                  sFrame.len += pMgmt->wWPAIELen;
3493              }
3494          }
3495     }
3496
3497     // Adjust the length fields
3498     pTxPacket->cbMPDULen = sFrame.len;
3499     pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3500
3501     return pTxPacket;
3502 }
3503
3504
3505
3506 /*+
3507  *
3508  * Routine Description:
3509  *  Constructs an association request frame
3510  *
3511  *
3512  * Return Value:
3513  *    A ptr to frame or NULL on allocation failue
3514  *
3515 -*/
3516
3517
3518 PSTxMgmtPacket
3519 s_MgrMakeAssocRequest(
3520      PSDevice pDevice,
3521      PSMgmtObject pMgmt,
3522      PBYTE pDAddr,
3523      WORD wCurrCapInfo,
3524      WORD wListenInterval,
3525      PWLAN_IE_SSID pCurrSSID,
3526      PWLAN_IE_SUPP_RATES pCurrRates,
3527      PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3528     )
3529 {
3530     PSTxMgmtPacket      pTxPacket = NULL;
3531     WLAN_FR_ASSOCREQ    sFrame;
3532     PBYTE               pbyIEs;
3533     PBYTE               pbyRSN;
3534
3535
3536     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3537     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3538     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
3539     // Setup the sFrame structure.
3540     sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
3541     sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
3542     // format fixed field frame structure
3543     vMgrEncodeAssocRequest(&sFrame);
3544     // Setup the header
3545     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3546         (
3547         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3548         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
3549         ));
3550     memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3551     memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3552     memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3553
3554     // Set the capibility and listen interval
3555     *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3556     *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3557
3558     // sFrame.len point to end of fixed field
3559     sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3560     sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3561     memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3562
3563     pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3564     pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3565     pbyIEs = pMgmt->sAssocInfo.abyIEs;
3566     memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3567     pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3568
3569     // Copy the rate set
3570     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3571     if ((pDevice->byBBType == BB_TYPE_11B) && (pCurrRates->len > 4))
3572         sFrame.len += 4 + WLAN_IEHDR_LEN;
3573     else
3574         sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3575     memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3576
3577     // Copy the extension rate set
3578     if ((pDevice->byBBType == BB_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3579         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3580         sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3581         memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3582     }
3583
3584     pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3585     memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3586     pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3587
3588
3589     if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3590          (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3591          (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3592         (pMgmt->pCurrBSS != NULL)) {
3593         /* WPA IE */
3594         sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3595         sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3596         sFrame.pRSNWPA->len = 16;
3597         sFrame.pRSNWPA->abyOUI[0] = 0x00;
3598         sFrame.pRSNWPA->abyOUI[1] = 0x50;
3599         sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3600         sFrame.pRSNWPA->abyOUI[3] = 0x01;
3601         sFrame.pRSNWPA->wVersion = 1;
3602         //Group Key Cipher Suite
3603         sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3604         sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3605         sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3606         if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3607             sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3608         } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3609             sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3610         } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3611             sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3612         } else {
3613             sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3614         }
3615         // Pairwise Key Cipher Suite
3616         sFrame.pRSNWPA->wPKCount = 1;
3617         sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3618         sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3619         sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3620         if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3621             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3622         } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3623             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3624         } else {
3625             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3626         }
3627         // Auth Key Management Suite
3628         pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3629         *pbyRSN++=0x01;
3630         *pbyRSN++=0x00;
3631         *pbyRSN++=0x00;
3632
3633         *pbyRSN++=0x50;
3634         *pbyRSN++=0xf2;
3635         if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
3636             *pbyRSN++=WPA_AUTH_PSK;
3637         }
3638         else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
3639             *pbyRSN++=WPA_AUTH_IEEE802_1X;
3640         }
3641         else {
3642             *pbyRSN++=WPA_NONE;
3643         }
3644
3645         sFrame.pRSNWPA->len +=6;
3646
3647         // RSN Capabilites
3648
3649         *pbyRSN++=0x00;
3650         *pbyRSN++=0x00;
3651         sFrame.pRSNWPA->len +=2;
3652
3653         sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3654         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3655         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3656         memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3657         pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3658
3659     } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3660                 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3661                (pMgmt->pCurrBSS != NULL)) {
3662         unsigned int ii;
3663         PWORD               pwPMKID;
3664
3665         // WPA IE
3666         sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3667         sFrame.pRSN->byElementID = WLAN_EID_RSN;
3668         sFrame.pRSN->len = 6; //Version(2)+GK(4)
3669         sFrame.pRSN->wVersion = 1;
3670         //Group Key Cipher Suite
3671         sFrame.pRSN->abyRSN[0] = 0x00;
3672         sFrame.pRSN->abyRSN[1] = 0x0F;
3673         sFrame.pRSN->abyRSN[2] = 0xAC;
3674         if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3675             sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3676         } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3677             sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3678         } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3679             sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3680         } else {
3681             sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3682         }
3683
3684         // Pairwise Key Cipher Suite
3685         sFrame.pRSN->abyRSN[4] = 1;
3686         sFrame.pRSN->abyRSN[5] = 0;
3687         sFrame.pRSN->abyRSN[6] = 0x00;
3688         sFrame.pRSN->abyRSN[7] = 0x0F;
3689         sFrame.pRSN->abyRSN[8] = 0xAC;
3690         if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3691             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3692         } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3693             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3694         } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
3695             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3696         } else {
3697             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3698         }
3699         sFrame.pRSN->len += 6;
3700
3701         // Auth Key Management Suite
3702         sFrame.pRSN->abyRSN[10] = 1;
3703         sFrame.pRSN->abyRSN[11] = 0;
3704         sFrame.pRSN->abyRSN[12] = 0x00;
3705         sFrame.pRSN->abyRSN[13] = 0x0F;
3706         sFrame.pRSN->abyRSN[14] = 0xAC;
3707         if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
3708             sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3709         } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
3710             sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3711         } else {
3712             sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3713         }
3714         sFrame.pRSN->len +=6;
3715
3716         // RSN Capabilites
3717         if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
3718             memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3719         } else {
3720             sFrame.pRSN->abyRSN[16] = 0;
3721             sFrame.pRSN->abyRSN[17] = 0;
3722         }
3723         sFrame.pRSN->len +=2;
3724
3725         if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3726             // RSN PMKID
3727             pbyRSN = &sFrame.pRSN->abyRSN[18];
3728             pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
3729             *pwPMKID = 0;            // Initialize PMKID count
3730             pbyRSN += 2;             // Point to PMKID list
3731         for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3732                 if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0],
3733                              pMgmt->abyCurrBSSID,
3734                              ETH_ALEN)) {
3735                         (*pwPMKID)++;
3736                         memcpy(pbyRSN,
3737                                pDevice->gsPMKID.BSSIDInfo[ii].PMKID,
3738                                16);
3739                         pbyRSN += 16;
3740                 }
3741         }
3742             if (*pwPMKID != 0) {
3743                 sFrame.pRSN->len += (2 + (*pwPMKID)*16);
3744             }
3745         }
3746
3747         sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3748         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3749         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3750         memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
3751         pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3752     }
3753
3754
3755     // Adjust the length fields
3756     pTxPacket->cbMPDULen = sFrame.len;
3757     pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3758     return pTxPacket;
3759 }
3760
3761
3762
3763
3764
3765
3766
3767
3768 /*+
3769  *
3770  * Routine Description:
3771  *  Constructs an re-association request frame
3772  *
3773  *
3774  * Return Value:
3775  *    A ptr to frame or NULL on allocation failue
3776  *
3777 -*/
3778
3779
3780 PSTxMgmtPacket
3781 s_MgrMakeReAssocRequest(
3782      PSDevice pDevice,
3783      PSMgmtObject pMgmt,
3784      PBYTE pDAddr,
3785      WORD wCurrCapInfo,
3786      WORD wListenInterval,
3787      PWLAN_IE_SSID pCurrSSID,
3788      PWLAN_IE_SUPP_RATES pCurrRates,
3789      PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3790     )
3791 {
3792     PSTxMgmtPacket      pTxPacket = NULL;
3793     WLAN_FR_REASSOCREQ  sFrame;
3794     PBYTE               pbyIEs;
3795     PBYTE               pbyRSN;
3796
3797
3798     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3799     memset( pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
3800     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
3801     /* Setup the sFrame structure. */
3802     sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
3803     sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
3804
3805     // format fixed field frame structure
3806     vMgrEncodeReassocRequest(&sFrame);
3807
3808     /* Setup the header */
3809     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3810         (
3811         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3812         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
3813         ));
3814     memcpy( sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3815     memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3816     memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3817
3818     /* Set the capibility and listen interval */
3819     *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3820     *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3821
3822     memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3823     /* Copy the SSID */
3824     /* sFrame.len point to end of fixed field */
3825     sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3826     sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3827     memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3828
3829     pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3830     pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3831     pbyIEs = pMgmt->sAssocInfo.abyIEs;
3832     memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3833     pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3834
3835     /* Copy the rate set */
3836     /* sFrame.len point to end of SSID */
3837     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3838     sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3839     memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3840
3841     // Copy the extension rate set
3842     if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3843         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3844         sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3845         memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3846     }
3847
3848     pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3849     memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3850     pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3851
3852     if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3853          (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3854          (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3855         (pMgmt->pCurrBSS != NULL)) {
3856         /* WPA IE */
3857         sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3858         sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3859         sFrame.pRSNWPA->len = 16;
3860         sFrame.pRSNWPA->abyOUI[0] = 0x00;
3861         sFrame.pRSNWPA->abyOUI[1] = 0x50;
3862         sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3863         sFrame.pRSNWPA->abyOUI[3] = 0x01;
3864         sFrame.pRSNWPA->wVersion = 1;
3865         //Group Key Cipher Suite
3866         sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3867         sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3868         sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3869         if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3870             sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3871         } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3872             sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3873         } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3874             sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3875         } else {
3876             sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3877         }
3878         // Pairwise Key Cipher Suite
3879         sFrame.pRSNWPA->wPKCount = 1;
3880         sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3881         sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3882         sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3883         if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3884             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3885         } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3886             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3887         } else {
3888             sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3889         }
3890         // Auth Key Management Suite
3891         pbyRSN = (PBYTE)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3892         *pbyRSN++=0x01;
3893         *pbyRSN++=0x00;
3894         *pbyRSN++=0x00;
3895
3896         *pbyRSN++=0x50;
3897         *pbyRSN++=0xf2;
3898         if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) {
3899             *pbyRSN++=WPA_AUTH_PSK;
3900         } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA) {
3901             *pbyRSN++=WPA_AUTH_IEEE802_1X;
3902         } else {
3903             *pbyRSN++=WPA_NONE;
3904         }
3905
3906         sFrame.pRSNWPA->len +=6;
3907
3908         // RSN Capabilites
3909         *pbyRSN++=0x00;
3910         *pbyRSN++=0x00;
3911         sFrame.pRSNWPA->len +=2;
3912
3913         sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3914         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3915         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3916         memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3917         pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3918
3919     } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3920                 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3921                (pMgmt->pCurrBSS != NULL)) {
3922         unsigned int ii;
3923         PWORD               pwPMKID;
3924
3925         /* WPA IE */
3926         sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3927         sFrame.pRSN->byElementID = WLAN_EID_RSN;
3928         sFrame.pRSN->len = 6; //Version(2)+GK(4)
3929         sFrame.pRSN->wVersion = 1;
3930         //Group Key Cipher Suite
3931         sFrame.pRSN->abyRSN[0] = 0x00;
3932         sFrame.pRSN->abyRSN[1] = 0x0F;
3933         sFrame.pRSN->abyRSN[2] = 0xAC;
3934         if (pMgmt->byCSSGK == KEY_CTL_WEP) {
3935             sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3936         } else if (pMgmt->byCSSGK == KEY_CTL_TKIP) {
3937             sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3938         } else if (pMgmt->byCSSGK == KEY_CTL_CCMP) {
3939             sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3940         } else {
3941             sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3942         }
3943
3944         // Pairwise Key Cipher Suite
3945         sFrame.pRSN->abyRSN[4] = 1;
3946         sFrame.pRSN->abyRSN[5] = 0;
3947         sFrame.pRSN->abyRSN[6] = 0x00;
3948         sFrame.pRSN->abyRSN[7] = 0x0F;
3949         sFrame.pRSN->abyRSN[8] = 0xAC;
3950         if (pMgmt->byCSSPK == KEY_CTL_TKIP) {
3951             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3952         } else if (pMgmt->byCSSPK == KEY_CTL_CCMP) {
3953             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3954         } else if (pMgmt->byCSSPK == KEY_CTL_NONE) {
3955             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3956         } else {
3957             sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3958         }
3959         sFrame.pRSN->len += 6;
3960
3961         // Auth Key Management Suite
3962         sFrame.pRSN->abyRSN[10] = 1;
3963         sFrame.pRSN->abyRSN[11] = 0;
3964         sFrame.pRSN->abyRSN[12] = 0x00;
3965         sFrame.pRSN->abyRSN[13] = 0x0F;
3966         sFrame.pRSN->abyRSN[14] = 0xAC;
3967         if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK) {
3968             sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3969         } else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
3970             sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3971         } else {
3972             sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3973         }
3974         sFrame.pRSN->len +=6;
3975
3976         // RSN Capabilites
3977         if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist == TRUE) {
3978             memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3979         } else {
3980             sFrame.pRSN->abyRSN[16] = 0;
3981             sFrame.pRSN->abyRSN[17] = 0;
3982         }
3983         sFrame.pRSN->len +=2;
3984
3985         if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && (pDevice->bRoaming == TRUE) && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3986             // RSN PMKID
3987             pbyRSN = &sFrame.pRSN->abyRSN[18];
3988             pwPMKID = (PWORD)pbyRSN; // Point to PMKID count
3989             *pwPMKID = 0;            // Initialize PMKID count
3990             pbyRSN += 2;             // Point to PMKID list
3991             for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3992                 if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0],
3993                             pMgmt->abyCurrBSSID,
3994                             ETH_ALEN)) {
3995                         (*pwPMKID)++;
3996                         memcpy(pbyRSN,
3997                                pDevice->gsPMKID.BSSIDInfo[ii].PMKID,
3998                                16);
3999                         pbyRSN += 16;
4000                 }
4001             }
4002             if (*pwPMKID != 0) {
4003                 sFrame.pRSN->len += (2 + (*pwPMKID)*16);
4004             }
4005         }
4006
4007         sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
4008         // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
4009         pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
4010         memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
4011         pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
4012     }
4013
4014
4015
4016     /* Adjust the length fields */
4017     pTxPacket->cbMPDULen = sFrame.len;
4018     pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4019
4020     return pTxPacket;
4021 }
4022
4023 /*+
4024  *
4025  * Routine Description:
4026  *  Constructs an assoc-response frame
4027  *
4028  *
4029  * Return Value:
4030  *    PTR to frame; or NULL on allocation failue
4031  *
4032 -*/
4033
4034 PSTxMgmtPacket
4035 s_MgrMakeAssocResponse(
4036      PSDevice pDevice,
4037      PSMgmtObject pMgmt,
4038      WORD wCurrCapInfo,
4039      WORD wAssocStatus,
4040      WORD wAssocAID,
4041      PBYTE pDstAddr,
4042      PWLAN_IE_SUPP_RATES pCurrSuppRates,
4043      PWLAN_IE_SUPP_RATES pCurrExtSuppRates
4044     )
4045 {
4046     PSTxMgmtPacket      pTxPacket = NULL;
4047     WLAN_FR_ASSOCRESP   sFrame;
4048
4049
4050     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
4051     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
4052     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
4053     // Setup the sFrame structure
4054     sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
4055     sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
4056     vMgrEncodeAssocResponse(&sFrame);
4057     // Setup the header
4058     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
4059         (
4060         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
4061         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
4062         ));
4063     memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
4064     memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
4065     memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
4066
4067     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
4068     *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
4069     *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
4070
4071     // Copy the rate set
4072     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4073     sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
4074     memcpy(sFrame.pSuppRates,
4075            pCurrSuppRates,
4076            ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
4077           );
4078
4079     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
4080         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4081         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
4082         memcpy(sFrame.pExtSuppRates,
4083              pCurrExtSuppRates,
4084              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
4085              );
4086     }
4087
4088     // Adjust the length fields
4089     pTxPacket->cbMPDULen = sFrame.len;
4090     pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4091
4092     return pTxPacket;
4093 }
4094
4095
4096 /*+
4097  *
4098  * Routine Description:
4099  *  Constructs an reassoc-response frame
4100  *
4101  *
4102  * Return Value:
4103  *    PTR to frame; or NULL on allocation failue
4104  *
4105 -*/
4106
4107
4108 PSTxMgmtPacket
4109 s_MgrMakeReAssocResponse(
4110      PSDevice pDevice,
4111      PSMgmtObject pMgmt,
4112      WORD wCurrCapInfo,
4113      WORD wAssocStatus,
4114      WORD wAssocAID,
4115      PBYTE pDstAddr,
4116      PWLAN_IE_SUPP_RATES pCurrSuppRates,
4117      PWLAN_IE_SUPP_RATES pCurrExtSuppRates
4118     )
4119 {
4120     PSTxMgmtPacket      pTxPacket = NULL;
4121     WLAN_FR_REASSOCRESP   sFrame;
4122
4123
4124     pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
4125     memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
4126     pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
4127     // Setup the sFrame structure
4128     sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
4129     sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
4130     vMgrEncodeReassocResponse(&sFrame);
4131     // Setup the header
4132     sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
4133         (
4134         WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
4135         WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
4136         ));
4137     memcpy( sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
4138     memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
4139     memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
4140
4141     *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
4142     *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
4143     *sFrame.pwAid = cpu_to_le16((WORD)(wAssocAID | BIT14 | BIT15));
4144
4145     // Copy the rate set
4146     sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4147     sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
4148     memcpy(sFrame.pSuppRates,
4149              pCurrSuppRates,
4150              ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
4151              );
4152
4153     if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
4154         sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
4155         sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
4156         memcpy(sFrame.pExtSuppRates,
4157              pCurrExtSuppRates,
4158              ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
4159              );
4160     }
4161
4162     // Adjust the length fields
4163     pTxPacket->cbMPDULen = sFrame.len;
4164     pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
4165
4166     return pTxPacket;
4167 }
4168
4169
4170 /*+
4171  *
4172  * Routine Description:
4173  *  Handles probe response management frames.
4174  *
4175  *
4176  * Return Value:
4177  *    none.
4178  *
4179 -*/
4180
4181 static
4182 void
4183 s_vMgrRxProbeResponse(
4184      PSDevice pDevice,
4185      PSMgmtObject pMgmt,
4186      PSRxMgmtPacket pRxPacket
4187     )
4188 {
4189     PKnownBSS           pBSSList = NULL;
4190     WLAN_FR_PROBERESP   sFrame;
4191     BYTE                byCurrChannel = pRxPacket->byRxChannel;
4192     ERPObject           sERP;
4193     BOOL                bChannelHit = TRUE;
4194
4195
4196     memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
4197     // decode the frame
4198     sFrame.len = pRxPacket->cbMPDULen;
4199     sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
4200     vMgrDecodeProbeResponse(&sFrame);
4201
4202     if ((sFrame.pqwTimestamp == NULL)
4203         || (sFrame.pwBeaconInterval == NULL)
4204         || (sFrame.pwCapInfo == NULL)
4205         || (sFrame.pSSID == NULL)
4206         || (sFrame.pSuppRates == NULL)) {
4207
4208         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p]\n",
4209                 pRxPacket->p80211Header);
4210         DBG_PORT80(0xCC);
4211         return;
4212     }
4213
4214     if(sFrame.pSSID->len == 0)
4215        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
4216
4217
4218     //{{ RobertYu:20050201, 11a  byCurrChannel != sFrame.pDSParms->byCurrChannel mapping
4219     if( byCurrChannel > CB_MAX_CHANNEL_24G )
4220     {
4221         if (sFrame.pDSParms) {
4222                 if (byCurrChannel ==
4223                     RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1])
4224                         bChannelHit = TRUE;
4225                 byCurrChannel =
4226                         RFaby11aChannelIndex[sFrame.pDSParms->byCurrChannel-1];
4227         } else {
4228                 bChannelHit = TRUE;
4229         }
4230     } else {
4231         if (sFrame.pDSParms) {
4232                 if (byCurrChannel == sFrame.pDSParms->byCurrChannel)
4233                         bChannelHit = TRUE;
4234                 byCurrChannel = sFrame.pDSParms->byCurrChannel;
4235         } else {
4236                 bChannelHit = TRUE;
4237         }
4238     }
4239     //RobertYu:20050201
4240
4241 if(ChannelExceedZoneType(pDevice,byCurrChannel)==TRUE)
4242       return;
4243
4244     if (sFrame.pERP) {
4245         sERP.byERP = sFrame.pERP->byContext;
4246         sERP.bERPExist = TRUE;
4247     } else {
4248         sERP.bERPExist = FALSE;
4249         sERP.byERP = 0;
4250     }
4251
4252
4253     // update or insert the bss
4254     pBSSList = BSSpAddrIsInBSSList((void *) pDevice,
4255                                    sFrame.pHdr->sA3.abyAddr3,
4256                                    sFrame.pSSID);
4257     if (pBSSList) {
4258         BSSbUpdateToBSSList((void *) pDevice,
4259                             *sFrame.pqwTimestamp,
4260                             *sFrame.pwBeaconInterval,
4261                             *sFrame.pwCapInfo,
4262                             byCurrChannel,
4263                             bChannelHit,
4264                             sFrame.pSSID,
4265                             sFrame.pSuppRates,
4266                             sFrame.pExtSuppRates,
4267                             &sERP,
4268                             sFrame.pRSN,
4269                             sFrame.pRSNWPA,
4270                             sFrame.pIE_Country,
4271                             sFrame.pIE_Quiet,
4272                             pBSSList,
4273                             sFrame.len - WLAN_HDR_ADDR3_LEN,
4274                             /* payload of probresponse */
4275                             sFrame.pHdr->sA4.abyAddr4,
4276                             (void *) pRxPacket);
4277     } else {
4278         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
4279         BSSbInsertToBSSList((void *) pDevice,
4280                             sFrame.pHdr->sA3.abyAddr3,
4281                             *sFrame.pqwTimestamp,
4282                             *sFrame.pwBeaconInterval,
4283                             *sFrame.pwCapInfo,
4284                             byCurrChannel,
4285                             sFrame.pSSID,
4286                             sFrame.pSuppRates,
4287                             sFrame.pExtSuppRates,
4288                             &sERP,
4289                             sFrame.pRSN,
4290                             sFrame.pRSNWPA,
4291                             sFrame.pIE_Country,
4292                             sFrame.pIE_Quiet,
4293                             sFrame.len - WLAN_HDR_ADDR3_LEN,
4294                             sFrame.pHdr->sA4.abyAddr4,   /* payload of beacon */
4295                             (void *) pRxPacket);
4296     }
4297     return;
4298
4299 }
4300
4301 /*+
4302  *
4303  * Routine Description:(AP)or(Ad-hoc STA)
4304  *  Handles probe request management frames.
4305  *
4306  *
4307  * Return Value:
4308  *    none.
4309  *
4310 -*/
4311
4312
4313 static
4314 void
4315 s_vMgrRxProbeRequest(
4316      PSDevice pDevice,
4317      PSMgmtObject pMgmt,
4318      PSRxMgmtPacket pRxPacket
4319     )
4320 {
4321     WLAN_FR_PROBEREQ    sFrame;
4322     CMD_STATUS          Status;
4323     PSTxMgmtPacket      pTxPacket;
4324     BYTE                byPHYType = BB_TYPE_11B;
4325
4326     // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
4327     // STA have to response this request.
4328     if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
4329         ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
4330
4331         memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
4332         // decode the frame
4333         sFrame.len = pRxPacket->cbMPDULen;
4334         sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
4335         vMgrDecodeProbeRequest(&sFrame);
4336 /*
4337         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n",
4338                   sFrame.pHdr->sA3.abyAddr2[0],
4339                   sFrame.pHdr->sA3.abyAddr2[1],
4340                   sFrame.pHdr->sA3.abyAddr2[2],
4341                   sFrame.pHdr->sA3.abyAddr2[3],
4342                   sFrame.pHdr->sA3.abyAddr2[4],
4343                   sFrame.pHdr->sA3.abyAddr2[5]
4344                 );
4345 */
4346         if (sFrame.pSSID->len != 0) {
4347             if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
4348                 return;
4349             if (memcmp(sFrame.pSSID->abySSID,
4350                        ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
4351                        ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
4352                        return;
4353             }
4354         }
4355
4356         if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL)) {
4357             byPHYType = BB_TYPE_11G;
4358         }
4359
4360         // Probe response reply..
4361         pTxPacket = s_MgrMakeProbeResponse
4362                     (
4363                       pDevice,
4364                       pMgmt,
4365                       pMgmt->wCurrCapInfo,
4366                       pMgmt->wCurrBeaconPeriod,
4367                       pMgmt->uCurrChannel,
4368                       0,
4369                       sFrame.pHdr->sA3.abyAddr2,
4370                       (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4371                       (PBYTE)pMgmt->abyCurrBSSID,
4372                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4373                       (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
4374                        byPHYType
4375                     );
4376         if (pTxPacket != NULL ){
4377             /* send the frame */
4378             Status = csMgmt_xmit(pDevice, pTxPacket);
4379             if (Status != CMD_STATUS_PENDING) {
4380                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
4381             }
4382             else {
4383 //                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx sending..\n");
4384             }
4385         }
4386     }
4387
4388     return;
4389 }
4390
4391 /*+
4392  *
4393  * Routine Description:
4394  *
4395  *  Entry point for the reception and handling of 802.11 management
4396  *  frames. Makes a determination of the frame type and then calls
4397  *  the appropriate function.
4398  *
4399  *
4400  * Return Value:
4401  *    none.
4402  *
4403 -*/
4404
4405 void vMgrRxManagePacket(void *hDeviceContext,
4406                         PSMgmtObject pMgmt,
4407                         PSRxMgmtPacket pRxPacket)
4408 {
4409     PSDevice    pDevice = (PSDevice)hDeviceContext;
4410     BOOL        bInScan = FALSE;
4411     unsigned int        uNodeIndex = 0;
4412     NODE_STATE  eNodeState = 0;
4413     CMD_STATUS  Status;
4414
4415
4416     if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
4417         if (BSSbIsSTAInNodeDB(pDevice, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
4418             eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
4419     }
4420
4421     switch( WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl)) ){
4422
4423         case WLAN_FSTYPE_ASSOCREQ:
4424             // Frame Clase = 2
4425             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
4426             if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
4427                 (eNodeState < NODE_AUTH)) {
4428                 // send deauth notification
4429                 // reason = (6) class 2 received from nonauth sta
4430                 vMgrDeAuthenBeginSta(pDevice,
4431                                      pMgmt,
4432                                      pRxPacket->p80211Header->sA3.abyAddr2,
4433                                      (6),
4434                                      &Status
4435                                      );
4436                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
4437             }
4438             else {
4439                 s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4440             }
4441             break;
4442
4443         case WLAN_FSTYPE_ASSOCRESP:
4444             // Frame Clase = 2
4445             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
4446             s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, FALSE);
4447             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
4448             break;
4449
4450         case WLAN_FSTYPE_REASSOCREQ:
4451             // Frame Clase = 2
4452             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
4453             // Todo: reassoc
4454             if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
4455                (eNodeState < NODE_AUTH)) {
4456                 // send deauth notification
4457                 // reason = (6) class 2 received from nonauth sta
4458                 vMgrDeAuthenBeginSta(pDevice,
4459                                      pMgmt,
4460                                      pRxPacket->p80211Header->sA3.abyAddr2,
4461                                      (6),
4462                                      &Status
4463                                      );
4464                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
4465
4466             }
4467             s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4468             break;
4469
4470         case WLAN_FSTYPE_REASSOCRESP:
4471             // Frame Clase = 2
4472             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
4473             s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, TRUE);
4474             break;
4475
4476         case WLAN_FSTYPE_PROBEREQ:
4477             // Frame Clase = 0
4478             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx probereq\n");
4479             s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
4480             break;
4481
4482         case WLAN_FSTYPE_PROBERESP:
4483             // Frame Clase = 0
4484             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
4485
4486             s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
4487             break;
4488
4489         case WLAN_FSTYPE_BEACON:
4490             // Frame Clase = 0
4491             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
4492             if (pMgmt->eScanState != WMAC_NO_SCANNING) {
4493                 bInScan = TRUE;
4494             }
4495             s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
4496             break;
4497
4498         case WLAN_FSTYPE_ATIM:
4499             // Frame Clase = 1
4500             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
4501             break;
4502
4503         case WLAN_FSTYPE_DISASSOC:
4504             // Frame Clase = 2
4505             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
4506             if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) &&
4507                 (eNodeState < NODE_AUTH)) {
4508                 // send deauth notification
4509                 // reason = (6) class 2 received from nonauth sta
4510                 vMgrDeAuthenBeginSta(pDevice,
4511                                      pMgmt,
4512                                      pRxPacket->p80211Header->sA3.abyAddr2,
4513                                      (6),
4514                                      &Status
4515                                      );
4516                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
4517             }
4518             s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
4519             break;
4520
4521         case WLAN_FSTYPE_AUTHEN:
4522             // Frame Clase = 1
4523             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO  "rx authen\n");
4524             s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
4525             break;
4526
4527         case WLAN_FSTYPE_DEAUTHEN:
4528             // Frame Clase = 1
4529             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
4530             s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
4531             break;
4532
4533         default:
4534             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
4535     }
4536
4537     return;
4538 }
4539
4540 /*+
4541  *
4542  * Routine Description:
4543  *
4544  *
4545  *  Prepare beacon to send
4546  *
4547  * Return Value:
4548  *    TRUE if success; FALSE if failed.
4549  *
4550 -*/
4551 BOOL bMgrPrepareBeaconToSend(void *hDeviceContext, PSMgmtObject pMgmt)
4552 {
4553     PSDevice            pDevice = (PSDevice)hDeviceContext;
4554     PSTxMgmtPacket      pTxPacket;
4555
4556 //    pDevice->bBeaconBufReady = FALSE;
4557     if (pDevice->bEncryptionEnable || pDevice->bEnable8021x){
4558         pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
4559     }
4560     else {
4561         pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
4562     }
4563     pTxPacket = s_MgrMakeBeacon
4564                 (
4565                   pDevice,
4566                   pMgmt,
4567                   pMgmt->wCurrCapInfo,
4568                   pMgmt->wCurrBeaconPeriod,
4569                   pMgmt->uCurrChannel,
4570                   pMgmt->wCurrATIMWindow, //0,
4571                   (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4572                   (PBYTE)pMgmt->abyCurrBSSID,
4573                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4574                   (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
4575                 );
4576
4577     if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
4578         (pMgmt->abyCurrBSSID[0] == 0))
4579         return FALSE;
4580
4581     csBeacon_xmit(pDevice, pTxPacket);
4582     MACvRegBitsOn(pDevice, MAC_REG_TCR, TCR_AUTOBCNTX);
4583
4584     return TRUE;
4585 }
4586
4587
4588
4589
4590 /*+
4591  *
4592  * Routine Description:
4593  *
4594  *  Log a warning message based on the contents of the Status
4595  *  Code field of an 802.11 management frame.  Defines are
4596  *  derived from 802.11-1997 SPEC.
4597  *
4598  * Return Value:
4599  *    none.
4600  *
4601 -*/
4602 static
4603 void
4604 s_vMgrLogStatus(
4605      PSMgmtObject pMgmt,
4606      WORD  wStatus
4607     )
4608 {
4609     switch( wStatus ){
4610         case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
4611             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
4612             break;
4613         case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
4614             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
4615             break;
4616         case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
4617             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
4618             break;
4619         case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
4620             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
4621             break;
4622         case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
4623             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
4624             break;
4625         case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
4626             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
4627             break;
4628         case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
4629             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge  failure.\n");
4630             break;
4631         case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
4632             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
4633             break;
4634         case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
4635             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
4636             break;
4637         case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
4638             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
4639             break;
4640         case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
4641             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
4642             break;
4643         case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
4644             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
4645             break;
4646         case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
4647             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
4648             break;
4649         default:
4650             DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
4651             break;
4652     }
4653 }
4654
4655 /*
4656  *
4657  * Description:
4658  *    Add BSSID in PMKID Candidate list.
4659  *
4660  * Parameters:
4661  *  In:
4662  *      hDeviceContext - device structure point
4663  *      pbyBSSID - BSSID address for adding
4664  *      wRSNCap - BSS's RSN capability
4665  *  Out:
4666  *      none
4667  *
4668  * Return Value: none.
4669  *
4670 -*/
4671
4672 BOOL bAdd_PMKID_Candidate(void *hDeviceContext,
4673                           PBYTE pbyBSSID,
4674                           PSRSNCapObject psRSNCapObj)
4675 {
4676     PSDevice         pDevice = (PSDevice)hDeviceContext;
4677     PPMKID_CANDIDATE pCandidateList;
4678     unsigned int             ii = 0;
4679
4680     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4681
4682     if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
4683         return FALSE;
4684
4685     if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
4686         return FALSE;
4687
4688
4689
4690     // Update Old Candidate
4691     for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
4692         pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
4693         if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
4694                 if ((psRSNCapObj->bRSNCapExist == TRUE)
4695                     && (psRSNCapObj->wRSNCap & BIT0)) {
4696                         pCandidateList->Flags |=
4697                                 NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4698                 } else {
4699                         pCandidateList->Flags &=
4700                                 ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4701                 }
4702             return TRUE;
4703         }
4704     }
4705
4706     // New Candidate
4707     pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
4708     if ((psRSNCapObj->bRSNCapExist == TRUE) && (psRSNCapObj->wRSNCap & BIT0)) {
4709         pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4710     } else {
4711         pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4712     }
4713     memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
4714     pDevice->gsPMKIDCandidate.NumCandidates++;
4715     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4716     return TRUE;
4717 }
4718
4719 /*
4720  *
4721  * Description:
4722  *    Flush PMKID Candidate list.
4723  *
4724  * Parameters:
4725  *  In:
4726  *      hDeviceContext - device structure point
4727  *  Out:
4728  *      none
4729  *
4730  * Return Value: none.
4731  *
4732 -*/
4733
4734 void vFlush_PMKID_Candidate(void *hDeviceContext)
4735 {
4736     PSDevice        pDevice = (PSDevice)hDeviceContext;
4737
4738     if (pDevice == NULL)
4739         return;
4740
4741     memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
4742 }
4743
4744 static BOOL
4745 s_bCipherMatch (
4746      PKnownBSS                        pBSSNode,
4747      NDIS_802_11_ENCRYPTION_STATUS    EncStatus,
4748      PBYTE                           pbyCCSPK,
4749      PBYTE                           pbyCCSGK
4750     )
4751 {
4752     BYTE byMulticastCipher = KEY_CTL_INVALID;
4753     BYTE byCipherMask = 0x00;
4754     int i;
4755
4756     if (pBSSNode == NULL)
4757         return FALSE;
4758
4759     // check cap. of BSS
4760     if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4761          (EncStatus == Ndis802_11Encryption1Enabled)) {
4762         // default is WEP only
4763         byMulticastCipher = KEY_CTL_WEP;
4764     }
4765
4766     if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4767         (pBSSNode->bWPA2Valid == TRUE) &&
4768
4769         ((EncStatus == Ndis802_11Encryption3Enabled) ||
4770          (EncStatus == Ndis802_11Encryption2Enabled))) {
4771         //WPA2
4772         // check Group Key Cipher
4773         if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
4774             (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
4775             byMulticastCipher = KEY_CTL_WEP;
4776         } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
4777             byMulticastCipher = KEY_CTL_TKIP;
4778         } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
4779             byMulticastCipher = KEY_CTL_CCMP;
4780         } else {
4781             byMulticastCipher = KEY_CTL_INVALID;
4782         }
4783
4784         /* check Pairwise Key Cipher */
4785         for (i = 0; i < pBSSNode->wCSSPKCount; i++) {
4786                 if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
4787                     (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
4788                         /* this should not happen as defined 802.11i */
4789                         byCipherMask |= 0x01;
4790                 } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
4791                         byCipherMask |= 0x02;
4792                 } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
4793                         byCipherMask |= 0x04;
4794                 } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
4795                         /* use group key only ignore all others */
4796                         byCipherMask = 0;
4797                         i = pBSSNode->wCSSPKCount;
4798                 }
4799         }
4800
4801     } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4802                 (pBSSNode->bWPAValid == TRUE) &&
4803                 ((EncStatus == Ndis802_11Encryption2Enabled) || (EncStatus == Ndis802_11Encryption3Enabled))) {
4804         //WPA
4805         // check Group Key Cipher
4806         if ((pBSSNode->byGKType == WPA_WEP40) ||
4807             (pBSSNode->byGKType == WPA_WEP104)) {
4808             byMulticastCipher = KEY_CTL_WEP;
4809         } else if (pBSSNode->byGKType == WPA_TKIP) {
4810             byMulticastCipher = KEY_CTL_TKIP;
4811         } else if (pBSSNode->byGKType == WPA_AESCCMP) {
4812             byMulticastCipher = KEY_CTL_CCMP;
4813         } else {
4814             byMulticastCipher = KEY_CTL_INVALID;
4815         }
4816
4817         /* check Pairwise Key Cipher */
4818         for (i = 0; i < pBSSNode->wPKCount; i++) {
4819                 if (pBSSNode->abyPKType[i] == WPA_TKIP) {
4820                         byCipherMask |= 0x02;
4821                 } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
4822                         byCipherMask |= 0x04;
4823                 } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
4824                         /* use group key only ignore all others */
4825                         byCipherMask = 0;
4826                         i = pBSSNode->wPKCount;
4827                 }
4828         }
4829     }
4830
4831     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"%d, %d, %d, %d, EncStatus:%d\n",
4832         byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
4833
4834     // mask our cap. with BSS
4835     if (EncStatus == Ndis802_11Encryption1Enabled) {
4836
4837         // For supporting Cisco migration mode, don't care pairwise key cipher
4838         //if ((byMulticastCipher == KEY_CTL_WEP) &&
4839         //    (byCipherMask == 0)) {
4840         if ((byMulticastCipher == KEY_CTL_WEP) &&
4841             (byCipherMask == 0)) {
4842             *pbyCCSGK = KEY_CTL_WEP;
4843             *pbyCCSPK = KEY_CTL_NONE;
4844             return TRUE;
4845         } else {
4846             return FALSE;
4847         }
4848
4849     } else if (EncStatus == Ndis802_11Encryption2Enabled) {
4850         if ((byMulticastCipher == KEY_CTL_TKIP) &&
4851             (byCipherMask == 0)) {
4852             *pbyCCSGK = KEY_CTL_TKIP;
4853             *pbyCCSPK = KEY_CTL_NONE;
4854             return TRUE;
4855         } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4856                    ((byCipherMask & 0x02) != 0)) {
4857             *pbyCCSGK = KEY_CTL_WEP;
4858             *pbyCCSPK = KEY_CTL_TKIP;
4859             return TRUE;
4860         } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4861                    ((byCipherMask & 0x02) != 0)) {
4862             *pbyCCSGK = KEY_CTL_TKIP;
4863             *pbyCCSPK = KEY_CTL_TKIP;
4864             return TRUE;
4865         } else {
4866             return FALSE;
4867         }
4868     } else if (EncStatus == Ndis802_11Encryption3Enabled) {
4869         if ((byMulticastCipher == KEY_CTL_CCMP) &&
4870             (byCipherMask == 0)) {
4871             // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
4872             return FALSE;
4873         } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4874                    ((byCipherMask & 0x04) != 0)) {
4875             *pbyCCSGK = KEY_CTL_WEP;
4876             *pbyCCSPK = KEY_CTL_CCMP;
4877             return TRUE;
4878         } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4879                    ((byCipherMask & 0x04) != 0)) {
4880             *pbyCCSGK = KEY_CTL_TKIP;
4881             *pbyCCSPK = KEY_CTL_CCMP;
4882             return TRUE;
4883         } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
4884                    ((byCipherMask & 0x04) != 0)) {
4885             *pbyCCSGK = KEY_CTL_CCMP;
4886             *pbyCCSPK = KEY_CTL_CCMP;
4887             return TRUE;
4888         } else {
4889             return FALSE;
4890         }
4891     }
4892     return TRUE;
4893 }
4894
4895