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