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