Btrfs: device_list_add() should not update list when mounted
[linux/fpc-iii.git] / drivers / staging / vt6655 / wmgr.c
blob67384782b7022d0579962fe9d15e94525df2057c
1 /*
2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3 * All rights reserved.
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.
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.
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.
20 * File: wmgr.c
22 * Purpose: Handles the 802.11 management functions
24 * Author: Lyndon Chen
26 * Date: May 8, 2002
28 * Functions:
29 * nsMgrObjectInitial - Initialize Management Object data structure
30 * vMgrObjectReset - Reset Management Object data structure
31 * vMgrAssocBeginSta - Start associate function
32 * vMgrReAssocBeginSta - Start reassociate function
33 * vMgrDisassocBeginSta - Start disassociate function
34 * s_vMgrRxAssocRequest - Handle Rcv associate_request
35 * s_vMgrRxAssocResponse - Handle Rcv associate_response
36 * vMrgAuthenBeginSta - Start authentication function
37 * vMgrDeAuthenDeginSta - Start deauthentication function
38 * s_vMgrRxAuthentication - Handle Rcv authentication
39 * s_vMgrRxAuthenSequence_1 - Handle Rcv authentication sequence 1
40 * s_vMgrRxAuthenSequence_2 - Handle Rcv authentication sequence 2
41 * s_vMgrRxAuthenSequence_3 - Handle Rcv authentication sequence 3
42 * s_vMgrRxAuthenSequence_4 - Handle Rcv authentication sequence 4
43 * s_vMgrRxDisassociation - Handle Rcv disassociation
44 * s_vMgrRxBeacon - Handle Rcv Beacon
45 * vMgrCreateOwnIBSS - Create ad_hoc IBSS or AP BSS
46 * vMgrJoinBSSBegin - Join BSS function
47 * s_vMgrSynchBSS - Synch & adopt BSS parameters
48 * s_MgrMakeBeacon - Create Baecon frame
49 * s_MgrMakeProbeResponse - Create Probe Response frame
50 * s_MgrMakeAssocRequest - Create Associate Request frame
51 * s_MgrMakeReAssocRequest - Create ReAssociate Request frame
52 * s_vMgrRxProbeResponse - Handle Rcv probe_response
53 * s_vMrgRxProbeRequest - Handle Rcv probe_request
54 * bMgrPrepareBeaconToSend - Prepare Beacon frame
55 * s_vMgrLogStatus - Log 802.11 Status
56 * vMgrRxManagePacket - Rcv management frame dispatch function
57 * s_vMgrFormatTIM- Assembler TIM field of beacon
58 * vMgrTimerInit- Initial 1-sec and command call back funtions
60 * Revision History:
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"
83 #define PLICE_DEBUG
85 /*--------------------- Static Definitions -------------------------*/
87 /*--------------------- Static Classes ----------------------------*/
89 /*--------------------- Static Variables --------------------------*/
90 static int msglevel = MSG_LEVEL_INFO;
92 /*--------------------- Static Functions --------------------------*/
93 //2008-8-4 <add> by chester
94 static bool ChannelExceedZoneType(
95 PSDevice pDevice,
96 unsigned char byCurrChannel
99 // Association/diassociation functions
100 static
101 PSTxMgmtPacket
102 s_MgrMakeAssocRequest(
103 PSDevice pDevice,
104 PSMgmtObject pMgmt,
105 unsigned char *pDAddr,
106 unsigned short wCurrCapInfo,
107 unsigned short wListenInterval,
108 PWLAN_IE_SSID pCurrSSID,
109 PWLAN_IE_SUPP_RATES pCurrRates,
110 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
113 static
114 void
115 s_vMgrRxAssocRequest(
116 PSDevice pDevice,
117 PSMgmtObject pMgmt,
118 PSRxMgmtPacket pRxPacket,
119 unsigned int uNodeIndex
122 static
123 PSTxMgmtPacket
124 s_MgrMakeReAssocRequest(
125 PSDevice pDevice,
126 PSMgmtObject pMgmt,
127 unsigned char *pDAddr,
128 unsigned short wCurrCapInfo,
129 unsigned short wListenInterval,
130 PWLAN_IE_SSID pCurrSSID,
131 PWLAN_IE_SUPP_RATES pCurrRates,
132 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
135 static
136 void
137 s_vMgrRxAssocResponse(
138 PSDevice pDevice,
139 PSMgmtObject pMgmt,
140 PSRxMgmtPacket pRxPacket,
141 bool bReAssocType
144 static
145 void
146 s_vMgrRxDisassociation(
147 PSDevice pDevice,
148 PSMgmtObject pMgmt,
149 PSRxMgmtPacket pRxPacket
152 // Authentication/deauthen functions
153 static
154 void
155 s_vMgrRxAuthenSequence_1(
156 PSDevice pDevice,
157 PSMgmtObject pMgmt,
158 PWLAN_FR_AUTHEN pFrame
161 static
162 void
163 s_vMgrRxAuthenSequence_2(
164 PSDevice pDevice,
165 PSMgmtObject pMgmt,
166 PWLAN_FR_AUTHEN pFrame
169 static
170 void
171 s_vMgrRxAuthenSequence_3(
172 PSDevice pDevice,
173 PSMgmtObject pMgmt,
174 PWLAN_FR_AUTHEN pFrame
177 static
178 void
179 s_vMgrRxAuthenSequence_4(
180 PSDevice pDevice,
181 PSMgmtObject pMgmt,
182 PWLAN_FR_AUTHEN pFrame
185 static
186 void
187 s_vMgrRxAuthentication(
188 PSDevice pDevice,
189 PSMgmtObject pMgmt,
190 PSRxMgmtPacket pRxPacket
193 static
194 void
195 s_vMgrRxDeauthentication(
196 PSDevice pDevice,
197 PSMgmtObject pMgmt,
198 PSRxMgmtPacket pRxPacket
201 // Scan functions
202 // probe request/response functions
203 static
204 void
205 s_vMgrRxProbeRequest(
206 PSDevice pDevice,
207 PSMgmtObject pMgmt,
208 PSRxMgmtPacket pRxPacket
211 static
212 void
213 s_vMgrRxProbeResponse(
214 PSDevice pDevice,
215 PSMgmtObject pMgmt,
216 PSRxMgmtPacket pRxPacket
219 // beacon functions
220 static
221 void
222 s_vMgrRxBeacon(
223 PSDevice pDevice,
224 PSMgmtObject pMgmt,
225 PSRxMgmtPacket pRxPacket,
226 bool bInScan
229 static
230 void
231 s_vMgrFormatTIM(
232 PSMgmtObject pMgmt,
233 PWLAN_IE_TIM pTIM
236 static
237 PSTxMgmtPacket
238 s_MgrMakeBeacon(
239 PSDevice pDevice,
240 PSMgmtObject pMgmt,
241 unsigned short wCurrCapInfo,
242 unsigned short wCurrBeaconPeriod,
243 unsigned int uCurrChannel,
244 unsigned short wCurrATIMWinodw,
245 PWLAN_IE_SSID pCurrSSID,
246 unsigned char *pCurrBSSID,
247 PWLAN_IE_SUPP_RATES pCurrSuppRates,
248 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
251 // Association response
252 static
253 PSTxMgmtPacket
254 s_MgrMakeAssocResponse(
255 PSDevice pDevice,
256 PSMgmtObject pMgmt,
257 unsigned short wCurrCapInfo,
258 unsigned short wAssocStatus,
259 unsigned short wAssocAID,
260 unsigned char *pDstAddr,
261 PWLAN_IE_SUPP_RATES pCurrSuppRates,
262 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
265 // ReAssociation response
266 static
267 PSTxMgmtPacket
268 s_MgrMakeReAssocResponse(
269 PSDevice pDevice,
270 PSMgmtObject pMgmt,
271 unsigned short wCurrCapInfo,
272 unsigned short wAssocStatus,
273 unsigned short wAssocAID,
274 unsigned char *pDstAddr,
275 PWLAN_IE_SUPP_RATES pCurrSuppRates,
276 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
279 // Probe response
280 static
281 PSTxMgmtPacket
282 s_MgrMakeProbeResponse(
283 PSDevice pDevice,
284 PSMgmtObject pMgmt,
285 unsigned short wCurrCapInfo,
286 unsigned short wCurrBeaconPeriod,
287 unsigned int uCurrChannel,
288 unsigned short wCurrATIMWinodw,
289 unsigned char *pDstAddr,
290 PWLAN_IE_SSID pCurrSSID,
291 unsigned char *pCurrBSSID,
292 PWLAN_IE_SUPP_RATES pCurrSuppRates,
293 PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
294 unsigned char byPHYType
297 // received status
298 static
299 void
300 s_vMgrLogStatus(
301 PSMgmtObject pMgmt,
302 unsigned short wStatus
305 static
306 void
307 s_vMgrSynchBSS(
308 PSDevice pDevice,
309 unsigned int uBSSMode,
310 PKnownBSS pCurr,
311 PCMD_STATUS pStatus
314 static bool
315 s_bCipherMatch(
316 PKnownBSS pBSSNode,
317 NDIS_802_11_ENCRYPTION_STATUS EncStatus,
318 unsigned char *pbyCCSPK,
319 unsigned char *pbyCCSGK
322 static void Encyption_Rebuild(
323 PSDevice pDevice,
324 PKnownBSS pCurr
327 /*--------------------- Export Variables --------------------------*/
329 /*--------------------- Export Functions --------------------------*/
333 * Routine Description:
334 * Allocates and initializes the Management object.
336 * Return Value:
337 * Ndis_staus.
341 void
342 vMgrObjectInit(
343 void *hDeviceContext
346 PSDevice pDevice = (PSDevice)hDeviceContext;
347 PSMgmtObject pMgmt = pDevice->pMgmt;
348 int ii;
350 pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
351 pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
352 pMgmt->uCurrChannel = pDevice->uChannel;
353 for (ii = 0; ii < WLAN_BSSID_LEN; ii++)
354 pMgmt->abyDesireBSSID[ii] = 0xFF;
356 pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
357 pMgmt->byCSSPK = KEY_CTL_NONE;
358 pMgmt->byCSSGK = KEY_CTL_NONE;
359 pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
360 BSSvClearBSSList((void *)pDevice, false);
362 return;
367 * Routine Description:
368 * Initializes timer object
370 * Return Value:
371 * Ndis_staus.
375 void
376 vMgrTimerInit(
377 void *hDeviceContext
380 PSDevice pDevice = (PSDevice)hDeviceContext;
381 PSMgmtObject pMgmt = pDevice->pMgmt;
383 init_timer(&pMgmt->sTimerSecondCallback);
384 pMgmt->sTimerSecondCallback.data = (unsigned long) pDevice;
385 pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
386 pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
388 init_timer(&pDevice->sTimerCommand);
389 pDevice->sTimerCommand.data = (unsigned long) pDevice;
390 pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
391 pDevice->sTimerCommand.expires = RUN_AT(HZ);
393 #ifdef TxInSleep
394 init_timer(&pDevice->sTimerTxData);
395 pDevice->sTimerTxData.data = (unsigned long) pDevice;
396 pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData;
397 pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback
398 pDevice->fTxDataInSleep = false;
399 pDevice->IsTxDataTrigger = false;
400 pDevice->nTxDataTimeCout = 0;
401 #endif
403 pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
404 pDevice->uCmdDequeueIdx = 0;
405 pDevice->uCmdEnqueueIdx = 0;
407 return;
412 * Routine Description:
413 * Reset the management object structure.
415 * Return Value:
416 * None.
420 void
421 vMgrObjectReset(
422 void *hDeviceContext
425 PSDevice pDevice = (PSDevice)hDeviceContext;
426 PSMgmtObject pMgmt = pDevice->pMgmt;
428 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
429 pMgmt->eCurrState = WMAC_STATE_IDLE;
430 pDevice->bEnablePSMode = false;
431 // TODO: timer
433 return;
438 * Routine Description:
439 * Start the station association procedure. Namely, send an
440 * association request frame to the AP.
442 * Return Value:
443 * None.
447 void
448 vMgrAssocBeginSta(
449 void *hDeviceContext,
450 PSMgmtObject pMgmt,
451 PCMD_STATUS pStatus
454 PSDevice pDevice = (PSDevice)hDeviceContext;
455 PSTxMgmtPacket pTxPacket;
457 pMgmt->wCurrCapInfo = 0;
458 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
459 if (pDevice->bEncryptionEnable)
460 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
462 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
463 if (pMgmt->wListenInterval == 0)
464 pMgmt->wListenInterval = 1; // at least one.
466 // ERP Phy (802.11g) should support short preamble.
467 if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
468 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
469 if (CARDbIsShorSlotTime(pMgmt->pAdapter))
470 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
471 } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
472 if (CARDbIsShortPreamble(pMgmt->pAdapter))
473 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
475 if (pMgmt->b11hEnable)
476 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
478 /* build an assocreq frame and send it */
479 pTxPacket = s_MgrMakeAssocRequest
481 pDevice,
482 pMgmt,
483 pMgmt->abyCurrBSSID,
484 pMgmt->wCurrCapInfo,
485 pMgmt->wListenInterval,
486 (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
487 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
488 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
491 if (pTxPacket != NULL) {
492 /* send the frame */
493 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
494 if (*pStatus == CMD_STATUS_PENDING) {
495 pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
496 *pStatus = CMD_STATUS_SUCCESS;
498 } else {
499 *pStatus = CMD_STATUS_RESOURCES;
502 return;
507 * Routine Description:
508 * Start the station re-association procedure.
510 * Return Value:
511 * None.
515 void
516 vMgrReAssocBeginSta(
517 void *hDeviceContext,
518 PSMgmtObject pMgmt,
519 PCMD_STATUS pStatus
522 PSDevice pDevice = (PSDevice)hDeviceContext;
523 PSTxMgmtPacket pTxPacket;
525 pMgmt->wCurrCapInfo = 0;
526 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
527 if (pDevice->bEncryptionEnable)
528 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
530 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
532 if (pMgmt->wListenInterval == 0)
533 pMgmt->wListenInterval = 1; // at least one.
535 // ERP Phy (802.11g) should support short preamble.
536 if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
537 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
538 if (CARDbIsShorSlotTime(pMgmt->pAdapter))
539 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
540 } else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
541 if (CARDbIsShortPreamble(pMgmt->pAdapter))
542 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
545 if (pMgmt->b11hEnable)
546 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
548 pTxPacket = s_MgrMakeReAssocRequest
550 pDevice,
551 pMgmt,
552 pMgmt->abyCurrBSSID,
553 pMgmt->wCurrCapInfo,
554 pMgmt->wListenInterval,
555 (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
556 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
557 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
560 if (pTxPacket != NULL) {
561 /* send the frame */
562 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
563 if (*pStatus != CMD_STATUS_PENDING)
564 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
565 else
566 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
569 return;
574 * Routine Description:
575 * Send an dis-association request frame to the AP.
577 * Return Value:
578 * None.
582 void
583 vMgrDisassocBeginSta(
584 void *hDeviceContext,
585 PSMgmtObject pMgmt,
586 unsigned char *abyDestAddress,
587 unsigned short wReason,
588 PCMD_STATUS pStatus
591 PSDevice pDevice = (PSDevice)hDeviceContext;
592 PSTxMgmtPacket pTxPacket = NULL;
593 WLAN_FR_DISASSOC sFrame;
595 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
596 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
597 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
599 // Setup the sFrame structure
600 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
601 sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
603 // format fixed field frame structure
604 vMgrEncodeDisassociation(&sFrame);
606 // Setup the header
607 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
609 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
610 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
613 memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
614 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
615 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
617 // Set reason code
618 *(sFrame.pwReason) = cpu_to_le16(wReason);
619 pTxPacket->cbMPDULen = sFrame.len;
620 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
622 // send the frame
623 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
624 if (*pStatus == CMD_STATUS_PENDING) {
625 pMgmt->eCurrState = WMAC_STATE_IDLE;
626 *pStatus = CMD_STATUS_SUCCESS;
629 return;
634 * Routine Description:(AP function)
635 * Handle incoming station association request frames.
637 * Return Value:
638 * None.
642 static
643 void
644 s_vMgrRxAssocRequest(
645 PSDevice pDevice,
646 PSMgmtObject pMgmt,
647 PSRxMgmtPacket pRxPacket,
648 unsigned int uNodeIndex
651 WLAN_FR_ASSOCREQ sFrame;
652 CMD_STATUS Status;
653 PSTxMgmtPacket pTxPacket;
654 unsigned short wAssocStatus = 0;
655 unsigned short wAssocAID = 0;
656 unsigned int uRateLen = WLAN_RATES_MAXLEN;
657 unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
658 unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
660 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
661 return;
662 // node index not found
663 if (!uNodeIndex)
664 return;
666 //check if node is authenticated
667 //decode the frame
668 memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
669 memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
670 memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
671 sFrame.len = pRxPacket->cbMPDULen;
672 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
674 vMgrDecodeAssocRequest(&sFrame);
676 if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
677 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
678 pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
679 pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
680 pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
681 WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
682 // Todo: check sta basic rate, if ap can't support, set status code
683 if (pDevice->eCurrentPHYType == PHY_TYPE_11B)
684 uRateLen = WLAN_RATES_MAXLEN_11B;
686 abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
687 abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
688 (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
689 uRateLen);
690 abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
691 if (pDevice->eCurrentPHYType == PHY_TYPE_11G)
692 abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
693 (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
694 uRateLen);
695 else
696 abyCurrExtSuppRates[1] = 0;
698 RATEvParseMaxRate((void *)pDevice,
699 (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
700 (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
701 false, // do not change our basic rate
702 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
703 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
704 &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
705 &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
706 &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
709 // set max tx rate
710 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
711 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
712 #ifdef PLICE_DEBUG
713 printk("RxAssocRequest:wTxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
714 #endif
715 // Todo: check sta preamble, if ap can't support, set status code
716 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
717 WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
718 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
719 WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
720 pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
721 wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
722 wAssocAID = (unsigned short)uNodeIndex;
723 // check if ERP support
724 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
725 pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
727 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
728 // B only STA join
729 pDevice->bProtectMode = true;
730 pDevice->bNonERPPresent = true;
732 if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
733 pDevice->bBarkerPreambleMd = true;
735 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d \n", wAssocAID);
736 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
737 sFrame.pHdr->sA3.abyAddr2[0],
738 sFrame.pHdr->sA3.abyAddr2[1],
739 sFrame.pHdr->sA3.abyAddr2[2],
740 sFrame.pHdr->sA3.abyAddr2[3],
741 sFrame.pHdr->sA3.abyAddr2[4],
742 sFrame.pHdr->sA3.abyAddr2[5]
744 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
745 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
746 } else {
747 /* TODO: received STA under state1 handle */
748 return;
751 // assoc response reply..
752 pTxPacket = s_MgrMakeAssocResponse
754 pDevice,
755 pMgmt,
756 pMgmt->wCurrCapInfo,
757 wAssocStatus,
758 wAssocAID,
759 sFrame.pHdr->sA3.abyAddr2,
760 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
761 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
763 if (pTxPacket != NULL) {
764 if (pDevice->bEnableHostapd)
765 return;
767 /* send the frame */
768 Status = csMgmt_xmit(pDevice, pTxPacket);
769 if (Status != CMD_STATUS_PENDING)
770 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n");
771 else
772 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n");
775 return;
780 * Description:(AP function)
781 * Handle incoming station re-association request frames.
783 * Parameters:
784 * In:
785 * pMgmt - Management Object structure
786 * pRxPacket - Received Packet
787 * Out:
788 * none
790 * Return Value: None.
794 static
795 void
796 s_vMgrRxReAssocRequest(
797 PSDevice pDevice,
798 PSMgmtObject pMgmt,
799 PSRxMgmtPacket pRxPacket,
800 unsigned int uNodeIndex
803 WLAN_FR_REASSOCREQ sFrame;
804 CMD_STATUS Status;
805 PSTxMgmtPacket pTxPacket;
806 unsigned short wAssocStatus = 0;
807 unsigned short wAssocAID = 0;
808 unsigned int uRateLen = WLAN_RATES_MAXLEN;
809 unsigned char abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
810 unsigned char abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
812 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
813 return;
814 // node index not found
815 if (!uNodeIndex)
816 return;
817 //check if node is authenticated
818 //decode the frame
819 memset(&sFrame, 0, sizeof(WLAN_FR_REASSOCREQ));
820 sFrame.len = pRxPacket->cbMPDULen;
821 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
822 vMgrDecodeReassocRequest(&sFrame);
824 if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
825 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
826 pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
827 pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
828 pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
829 WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? true : false;
830 // Todo: check sta basic rate, if ap can't support, set status code
832 if (pDevice->eCurrentPHYType == PHY_TYPE_11B)
833 uRateLen = WLAN_RATES_MAXLEN_11B;
835 abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
836 abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
837 (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
838 uRateLen);
839 abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
840 if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
841 abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
842 (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
843 uRateLen);
844 } else {
845 abyCurrExtSuppRates[1] = 0;
848 RATEvParseMaxRate((void *)pDevice,
849 (PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
850 (PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
851 false, // do not change our basic rate
852 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
853 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
854 &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
855 &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
856 &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
859 // set max tx rate
860 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
861 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
862 #ifdef PLICE_DEBUG
863 printk("RxReAssocRequest:TxDataRate is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate);
864 #endif
865 // Todo: check sta preamble, if ap can't support, set status code
866 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble =
867 WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
868 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime =
869 WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
870 pMgmt->sNodeDBTable[uNodeIndex].wAID = (unsigned short)uNodeIndex;
871 wAssocStatus = WLAN_MGMT_STATUS_SUCCESS;
872 wAssocAID = (unsigned short)uNodeIndex;
874 // if suppurt ERP
875 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate > RATE_11M)
876 pMgmt->sNodeDBTable[uNodeIndex].bERPExist = true;
878 if (pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate <= RATE_11M) {
879 // B only STA join
880 pDevice->bProtectMode = true;
881 pDevice->bNonERPPresent = true;
883 if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble)
884 pDevice->bBarkerPreambleMd = true;
886 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d \n", wAssocAID);
887 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X \n",
888 sFrame.pHdr->sA3.abyAddr2[0],
889 sFrame.pHdr->sA3.abyAddr2[1],
890 sFrame.pHdr->sA3.abyAddr2[2],
891 sFrame.pHdr->sA3.abyAddr2[3],
892 sFrame.pHdr->sA3.abyAddr2[4],
893 sFrame.pHdr->sA3.abyAddr2[5]
895 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n",
896 pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate);
900 // assoc response reply..
901 pTxPacket = s_MgrMakeReAssocResponse
903 pDevice,
904 pMgmt,
905 pMgmt->wCurrCapInfo,
906 wAssocStatus,
907 wAssocAID,
908 sFrame.pHdr->sA3.abyAddr2,
909 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
910 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
913 if (pTxPacket != NULL) {
914 /* send the frame */
915 if (pDevice->bEnableHostapd)
916 return;
918 Status = csMgmt_xmit(pDevice, pTxPacket);
919 if (Status != CMD_STATUS_PENDING)
920 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n");
921 else
922 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n");
924 return;
929 * Routine Description:
930 * Handle incoming association response frames.
932 * Return Value:
933 * None.
937 static
938 void
939 s_vMgrRxAssocResponse(
940 PSDevice pDevice,
941 PSMgmtObject pMgmt,
942 PSRxMgmtPacket pRxPacket,
943 bool bReAssocType
946 WLAN_FR_ASSOCRESP sFrame;
947 PWLAN_IE_SSID pItemSSID;
948 unsigned char *pbyIEs;
949 viawget_wpa_header *wpahdr;
951 if (pMgmt->eCurrState == WMAC_STATE_ASSOCPENDING ||
952 pMgmt->eCurrState == WMAC_STATE_ASSOC) {
953 sFrame.len = pRxPacket->cbMPDULen;
954 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
955 // decode the frame
956 vMgrDecodeAssocResponse(&sFrame);
957 if ((sFrame.pwCapInfo == NULL) ||
958 (sFrame.pwStatus == NULL) ||
959 (sFrame.pwAid == NULL) ||
960 (sFrame.pSuppRates == NULL)) {
961 DBG_PORT80(0xCC);
962 return;
965 pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
966 pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
967 pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.AssociationId = *(sFrame.pwAid);
968 pMgmt->sAssocInfo.AssocInfo.AvailableResponseFixedIEs |= 0x07;
970 pMgmt->sAssocInfo.AssocInfo.ResponseIELength = sFrame.len - 24 - 6;
971 pMgmt->sAssocInfo.AssocInfo.OffsetResponseIEs = pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs + pMgmt->sAssocInfo.AssocInfo.RequestIELength;
972 pbyIEs = pMgmt->sAssocInfo.abyIEs;
973 pbyIEs += pMgmt->sAssocInfo.AssocInfo.RequestIELength;
974 memcpy(pbyIEs, (sFrame.pBuf + 24 + 6), pMgmt->sAssocInfo.AssocInfo.ResponseIELength);
976 // save values and set current BSS state
977 if (cpu_to_le16((*(sFrame.pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
978 // set AID
979 pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid)));
980 if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1))
981 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
983 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14 | BIT15));
984 pMgmt->eCurrState = WMAC_STATE_ASSOC;
985 BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
986 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyCurrSSID;
987 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID);
988 pDevice->bLinkPass = true;
989 pDevice->uBBVGADiffCount = 0;
990 if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
991 if (skb_tailroom(pDevice->skb) < (sizeof(viawget_wpa_header) + pMgmt->sAssocInfo.AssocInfo.ResponseIELength +
992 pMgmt->sAssocInfo.AssocInfo.RequestIELength)) { //data room not enough
993 dev_kfree_skb(pDevice->skb);
994 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
996 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
997 wpahdr->type = VIAWGET_ASSOC_MSG;
998 wpahdr->resp_ie_len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
999 wpahdr->req_ie_len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1000 memcpy(pDevice->skb->data + sizeof(viawget_wpa_header), pMgmt->sAssocInfo.abyIEs, wpahdr->req_ie_len);
1001 memcpy(pDevice->skb->data + sizeof(viawget_wpa_header) + wpahdr->req_ie_len,
1002 pbyIEs,
1003 wpahdr->resp_ie_len
1005 skb_put(pDevice->skb, sizeof(viawget_wpa_header) + wpahdr->resp_ie_len + wpahdr->req_ie_len);
1006 pDevice->skb->dev = pDevice->wpadev;
1007 skb_reset_mac_header(pDevice->skb);
1008 pDevice->skb->pkt_type = PACKET_HOST;
1009 pDevice->skb->protocol = htons(ETH_P_802_2);
1010 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1011 netif_rx(pDevice->skb);
1012 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1015 //2008-0409-07, <Add> by Einsn Liu
1016 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1018 unsigned char buf[512];
1019 size_t len;
1020 union iwreq_data wrqu;
1021 int we_event;
1023 memset(buf, 0, 512);
1025 len = pMgmt->sAssocInfo.AssocInfo.RequestIELength;
1026 if (len) {
1027 memcpy(buf, pMgmt->sAssocInfo.abyIEs, len);
1028 memset(&wrqu, 0, sizeof(wrqu));
1029 wrqu.data.length = len;
1030 we_event = IWEVASSOCREQIE;
1031 wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
1034 memset(buf, 0, 512);
1035 len = pMgmt->sAssocInfo.AssocInfo.ResponseIELength;
1037 if (len) {
1038 memcpy(buf, pbyIEs, len);
1039 memset(&wrqu, 0, sizeof(wrqu));
1040 wrqu.data.length = len;
1041 we_event = IWEVASSOCRESPIE;
1042 wireless_send_event(pDevice->dev, we_event, &wrqu, buf);
1045 memset(&wrqu, 0, sizeof(wrqu));
1046 memcpy(wrqu.ap_addr.sa_data, &pMgmt->abyCurrBSSID[0], ETH_ALEN);
1047 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1048 wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1050 #endif //#ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1051 //End Add -- //2008-0409-07, <Add> by Einsn Liu
1052 } else {
1053 if (bReAssocType) {
1054 pMgmt->eCurrState = WMAC_STATE_IDLE;
1055 } else {
1056 // jump back to the auth state and indicate the error
1057 pMgmt->eCurrState = WMAC_STATE_AUTH;
1059 s_vMgrLogStatus(pMgmt, cpu_to_le16((*(sFrame.pwStatus))));
1064 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1065 //need clear flags related to Networkmanager
1067 pDevice->bwextcount = 0;
1068 pDevice->bWPASuppWextEnabled = false;
1069 #endif
1071 if (pMgmt->eCurrState == WMAC_STATE_ASSOC)
1072 timer_expire(pDevice->sTimerCommand, 0);
1073 return;
1078 * Routine Description:
1079 * Start the station authentication procedure. Namely, send an
1080 * authentication frame to the AP.
1082 * Return Value:
1083 * None.
1087 void
1088 vMgrAuthenBeginSta(
1089 void *hDeviceContext,
1090 PSMgmtObject pMgmt,
1091 PCMD_STATUS pStatus
1094 PSDevice pDevice = (PSDevice)hDeviceContext;
1095 WLAN_FR_AUTHEN sFrame;
1096 PSTxMgmtPacket pTxPacket = NULL;
1098 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1099 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1100 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1101 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1102 sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1103 vMgrEncodeAuthen(&sFrame);
1104 /* insert values */
1105 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1107 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1108 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)
1110 memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN);
1111 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1112 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1113 if (pMgmt->bShareKeyAlgorithm)
1114 *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_SHAREDKEY);
1115 else
1116 *(sFrame.pwAuthAlgorithm) = cpu_to_le16(WLAN_AUTH_ALG_OPENSYSTEM);
1118 *(sFrame.pwAuthSequence) = cpu_to_le16(1);
1119 /* Adjust the length fields */
1120 pTxPacket->cbMPDULen = sFrame.len;
1121 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1123 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
1124 if (*pStatus == CMD_STATUS_PENDING) {
1125 pMgmt->eCurrState = WMAC_STATE_AUTHPENDING;
1126 *pStatus = CMD_STATUS_SUCCESS;
1129 return;
1134 * Routine Description:
1135 * Start the station(AP) deauthentication procedure. Namely, send an
1136 * deauthentication frame to the AP or Sta.
1138 * Return Value:
1139 * None.
1143 void
1144 vMgrDeAuthenBeginSta(
1145 void *hDeviceContext,
1146 PSMgmtObject pMgmt,
1147 unsigned char *abyDestAddress,
1148 unsigned short wReason,
1149 PCMD_STATUS pStatus
1152 PSDevice pDevice = (PSDevice)hDeviceContext;
1153 WLAN_FR_DEAUTHEN sFrame;
1154 PSTxMgmtPacket pTxPacket = NULL;
1156 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1157 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DEAUTHEN_FR_MAXLEN);
1158 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1159 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1160 sFrame.len = WLAN_DEAUTHEN_FR_MAXLEN;
1161 vMgrEncodeDeauthen(&sFrame);
1162 /* insert values */
1163 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1165 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1166 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DEAUTHEN)
1169 memcpy(sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
1170 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1171 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1173 *(sFrame.pwReason) = cpu_to_le16(wReason); // deauthen. bcs left BSS
1174 /* Adjust the length fields */
1175 pTxPacket->cbMPDULen = sFrame.len;
1176 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1178 *pStatus = csMgmt_xmit(pDevice, pTxPacket);
1179 if (*pStatus == CMD_STATUS_PENDING)
1180 *pStatus = CMD_STATUS_SUCCESS;
1182 return;
1187 * Routine Description:
1188 * Handle incoming authentication frames.
1190 * Return Value:
1191 * None.
1195 static
1196 void
1197 s_vMgrRxAuthentication(
1198 PSDevice pDevice,
1199 PSMgmtObject pMgmt,
1200 PSRxMgmtPacket pRxPacket
1203 WLAN_FR_AUTHEN sFrame;
1205 // we better be an AP or a STA in AUTHPENDING otherwise ignore
1206 if (!(pMgmt->eCurrMode == WMAC_MODE_ESS_AP ||
1207 pMgmt->eCurrState == WMAC_STATE_AUTHPENDING)) {
1208 return;
1211 // decode the frame
1212 sFrame.len = pRxPacket->cbMPDULen;
1213 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1214 vMgrDecodeAuthen(&sFrame);
1215 switch (cpu_to_le16((*(sFrame.pwAuthSequence)))) {
1216 case 1:
1217 //AP function
1218 s_vMgrRxAuthenSequence_1(pDevice, pMgmt, &sFrame);
1219 break;
1220 case 2:
1221 s_vMgrRxAuthenSequence_2(pDevice, pMgmt, &sFrame);
1222 break;
1223 case 3:
1224 //AP function
1225 s_vMgrRxAuthenSequence_3(pDevice, pMgmt, &sFrame);
1226 break;
1227 case 4:
1228 s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame);
1229 break;
1230 default:
1231 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n",
1232 cpu_to_le16((*(sFrame.pwAuthSequence))));
1233 break;
1235 return;
1240 * Routine Description:
1241 * Handles incoming authen frames with sequence 1. Currently
1242 * assumes we're an AP. So far, no one appears to use authentication
1243 * in Ad-Hoc mode.
1245 * Return Value:
1246 * None.
1250 static
1251 void
1252 s_vMgrRxAuthenSequence_1(
1253 PSDevice pDevice,
1254 PSMgmtObject pMgmt,
1255 PWLAN_FR_AUTHEN pFrame
1258 PSTxMgmtPacket pTxPacket = NULL;
1259 unsigned int uNodeIndex;
1260 WLAN_FR_AUTHEN sFrame;
1261 PSKeyItem pTransmitKey;
1263 // Insert a Node entry
1264 if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
1265 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
1266 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2,
1267 WLAN_ADDR_LEN);
1270 if (pMgmt->bShareKeyAlgorithm) {
1271 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_KNOWN;
1272 pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 1;
1273 } else {
1274 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
1277 // send auth reply
1278 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1279 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1280 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1281 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1282 sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1283 // format buffer structure
1284 vMgrEncodeAuthen(&sFrame);
1285 // insert values
1286 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1288 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1289 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1290 WLAN_SET_FC_ISWEP(0)
1292 memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
1293 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1294 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1295 *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1296 *(sFrame.pwAuthSequence) = cpu_to_le16(2);
1298 if (cpu_to_le16(*(pFrame->pwAuthAlgorithm)) == WLAN_AUTH_ALG_SHAREDKEY) {
1299 if (pMgmt->bShareKeyAlgorithm)
1300 *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1301 else
1302 *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
1303 } else {
1304 if (pMgmt->bShareKeyAlgorithm)
1305 *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG);
1306 else
1307 *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1310 if (pMgmt->bShareKeyAlgorithm &&
1311 (cpu_to_le16(*(sFrame.pwStatus)) == WLAN_MGMT_STATUS_SUCCESS)) {
1312 sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
1313 sFrame.len += WLAN_CHALLENGE_IE_LEN;
1314 sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
1315 sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
1316 memset(pMgmt->abyChallenge, 0, WLAN_CHALLENGE_LEN);
1317 // get group key
1318 if (KeybGetTransmitKey(&(pDevice->sKey), pDevice->abyBroadcastAddr, GROUP_KEY, &pTransmitKey) == true) {
1319 rc4_init(&pDevice->SBox, pDevice->abyPRNG, pTransmitKey->uKeyLength+3);
1320 rc4_encrypt(&pDevice->SBox, pMgmt->abyChallenge, pMgmt->abyChallenge, WLAN_CHALLENGE_LEN);
1322 memcpy(sFrame.pChallenge->abyChallenge, pMgmt->abyChallenge , WLAN_CHALLENGE_LEN);
1325 /* Adjust the length fields */
1326 pTxPacket->cbMPDULen = sFrame.len;
1327 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1328 // send the frame
1329 if (pDevice->bEnableHostapd)
1330 return;
1332 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx.. \n");
1333 if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
1334 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n");
1336 return;
1341 * Routine Description:
1342 * Handles incoming auth frames with sequence number 2. Currently
1343 * assumes we're a station.
1346 * Return Value:
1347 * None.
1351 static
1352 void
1353 s_vMgrRxAuthenSequence_2(
1354 PSDevice pDevice,
1355 PSMgmtObject pMgmt,
1356 PWLAN_FR_AUTHEN pFrame
1359 WLAN_FR_AUTHEN sFrame;
1360 PSTxMgmtPacket pTxPacket = NULL;
1362 switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) {
1363 case WLAN_AUTH_ALG_OPENSYSTEM:
1364 if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1365 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n");
1366 pMgmt->eCurrState = WMAC_STATE_AUTH;
1367 timer_expire(pDevice->sTimerCommand, 0);
1368 } else {
1369 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n");
1370 s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1371 pMgmt->eCurrState = WMAC_STATE_IDLE;
1374 break;
1376 case WLAN_AUTH_ALG_SHAREDKEY:
1378 if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1379 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1380 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1381 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1382 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1383 sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1384 // format buffer structure
1385 vMgrEncodeAuthen(&sFrame);
1386 // insert values
1387 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1389 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1390 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1391 WLAN_SET_FC_ISWEP(1)
1393 memcpy(sFrame.pHdr->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1394 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1395 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1396 *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1397 *(sFrame.pwAuthSequence) = cpu_to_le16(3);
1398 *(sFrame.pwStatus) = cpu_to_le16(WLAN_MGMT_STATUS_SUCCESS);
1399 sFrame.pChallenge = (PWLAN_IE_CHALLENGE)(sFrame.pBuf + sFrame.len);
1400 sFrame.len += WLAN_CHALLENGE_IE_LEN;
1401 sFrame.pChallenge->byElementID = WLAN_EID_CHALLENGE;
1402 sFrame.pChallenge->len = WLAN_CHALLENGE_LEN;
1403 memcpy(sFrame.pChallenge->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN);
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 (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
1409 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n");
1411 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n");
1412 } else {
1413 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n");
1414 s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1416 break;
1417 default:
1418 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm))));
1419 break;
1421 return;
1426 * Routine Description:
1427 * Handles incoming authen frames with sequence 3. Currently
1428 * assumes we're an AP. This function assumes the frame has
1429 * already been successfully decrypted.
1432 * Return Value:
1433 * None.
1437 static
1438 void
1439 s_vMgrRxAuthenSequence_3(
1440 PSDevice pDevice,
1441 PSMgmtObject pMgmt,
1442 PWLAN_FR_AUTHEN pFrame
1445 PSTxMgmtPacket pTxPacket = NULL;
1446 unsigned int uStatusCode = 0;
1447 unsigned int uNodeIndex = 0;
1448 WLAN_FR_AUTHEN sFrame;
1450 if (!WLAN_GET_FC_ISWEP(pFrame->pHdr->sA3.wFrameCtl)) {
1451 uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
1452 goto reply;
1454 if (BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) {
1455 if (pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence != 1) {
1456 uStatusCode = WLAN_MGMT_STATUS_RX_AUTH_NOSEQ;
1457 goto reply;
1459 if (memcmp(pMgmt->abyChallenge, pFrame->pChallenge->abyChallenge, WLAN_CHALLENGE_LEN) != 0) {
1460 uStatusCode = WLAN_MGMT_STATUS_CHALLENGE_FAIL;
1461 goto reply;
1463 } else {
1464 uStatusCode = WLAN_MGMT_STATUS_UNSPEC_FAILURE;
1465 goto reply;
1468 if (uNodeIndex) {
1469 pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_AUTH;
1470 pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0;
1472 uStatusCode = WLAN_MGMT_STATUS_SUCCESS;
1473 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n");
1475 reply:
1476 // send auth reply
1477 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
1478 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_AUTHEN_FR_MAXLEN);
1479 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
1480 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
1481 sFrame.len = WLAN_AUTHEN_FR_MAXLEN;
1482 // format buffer structure
1483 vMgrEncodeAuthen(&sFrame);
1484 /* insert values */
1485 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
1487 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
1488 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_AUTHEN)|
1489 WLAN_SET_FC_ISWEP(0)
1491 memcpy(sFrame.pHdr->sA3.abyAddr1, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
1492 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
1493 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
1494 *(sFrame.pwAuthAlgorithm) = *(pFrame->pwAuthAlgorithm);
1495 *(sFrame.pwAuthSequence) = cpu_to_le16(4);
1496 *(sFrame.pwStatus) = cpu_to_le16(uStatusCode);
1498 /* Adjust the length fields */
1499 pTxPacket->cbMPDULen = sFrame.len;
1500 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
1501 // send the frame
1502 if (pDevice->bEnableHostapd)
1503 return;
1505 if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING)
1506 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n");
1508 return;
1513 * Routine Description:
1514 * Handles incoming authen frames with sequence 4
1517 * Return Value:
1518 * None.
1521 static
1522 void
1523 s_vMgrRxAuthenSequence_4(
1524 PSDevice pDevice,
1525 PSMgmtObject pMgmt,
1526 PWLAN_FR_AUTHEN pFrame
1529 if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) {
1530 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n");
1531 pMgmt->eCurrState = WMAC_STATE_AUTH;
1532 timer_expire(pDevice->sTimerCommand, 0);
1533 } else{
1534 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n");
1535 s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus))));
1536 pMgmt->eCurrState = WMAC_STATE_IDLE;
1542 * Routine Description:
1543 * Handles incoming disassociation frames
1546 * Return Value:
1547 * None.
1551 static
1552 void
1553 s_vMgrRxDisassociation(
1554 PSDevice pDevice,
1555 PSMgmtObject pMgmt,
1556 PSRxMgmtPacket pRxPacket
1559 WLAN_FR_DISASSOC sFrame;
1560 unsigned int uNodeIndex = 0;
1561 viawget_wpa_header *wpahdr;
1563 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1564 // if is acting an AP..
1565 // a STA is leaving this BSS..
1566 sFrame.len = pRxPacket->cbMPDULen;
1567 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1568 if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
1569 BSSvRemoveOneNode(pDevice, uNodeIndex);
1570 else
1571 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n");
1573 } else if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1574 sFrame.len = pRxPacket->cbMPDULen;
1575 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1576 vMgrDecodeDisassociation(&sFrame);
1577 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason)));
1578 //TODO: do something let upper layer know or
1579 //try to send associate packet again because of inactivity timeout
1580 if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1581 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1582 wpahdr->type = VIAWGET_DISASSOC_MSG;
1583 wpahdr->resp_ie_len = 0;
1584 wpahdr->req_ie_len = 0;
1585 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1586 pDevice->skb->dev = pDevice->wpadev;
1587 skb_reset_mac_header(pDevice->skb);
1589 pDevice->skb->pkt_type = PACKET_HOST;
1590 pDevice->skb->protocol = htons(ETH_P_802_2);
1591 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1592 netif_rx(pDevice->skb);
1593 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1596 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1598 union iwreq_data wrqu;
1599 memset(&wrqu, 0, sizeof(wrqu));
1600 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1601 printk("wireless_send_event--->SIOCGIWAP(disassociated)\n");
1602 wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1604 #endif
1606 /* else, ignore it */
1608 return;
1613 * Routine Description:
1614 * Handles incoming deauthentication frames
1617 * Return Value:
1618 * None.
1622 static
1623 void
1624 s_vMgrRxDeauthentication(
1625 PSDevice pDevice,
1626 PSMgmtObject pMgmt,
1627 PSRxMgmtPacket pRxPacket
1630 WLAN_FR_DEAUTHEN sFrame;
1631 unsigned int uNodeIndex = 0;
1632 viawget_wpa_header *wpahdr;
1634 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
1635 //Todo:
1636 // if is acting an AP..
1637 // a STA is leaving this BSS..
1638 sFrame.len = pRxPacket->cbMPDULen;
1639 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1640 if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
1641 BSSvRemoveOneNode(pDevice, uNodeIndex);
1642 else
1643 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n");
1644 } else {
1645 if (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) {
1646 sFrame.len = pRxPacket->cbMPDULen;
1647 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1648 vMgrDecodeDeauthen(&sFrame);
1649 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason))));
1650 // TODO: update BSS list for specific BSSID if pre-authentication case
1651 if (ether_addr_equal(sFrame.pHdr->sA3.abyAddr3,
1652 pMgmt->abyCurrBSSID)) {
1653 if (pMgmt->eCurrState >= WMAC_STATE_AUTHPENDING) {
1654 pMgmt->sNodeDBTable[0].bActive = false;
1655 pMgmt->eCurrMode = WMAC_MODE_STANDBY;
1656 pMgmt->eCurrState = WMAC_STATE_IDLE;
1657 netif_stop_queue(pDevice->dev);
1658 pDevice->bLinkPass = false;
1662 if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
1663 wpahdr = (viawget_wpa_header *)pDevice->skb->data;
1664 wpahdr->type = VIAWGET_DISASSOC_MSG;
1665 wpahdr->resp_ie_len = 0;
1666 wpahdr->req_ie_len = 0;
1667 skb_put(pDevice->skb, sizeof(viawget_wpa_header));
1668 pDevice->skb->dev = pDevice->wpadev;
1669 skb_reset_mac_header(pDevice->skb);
1670 pDevice->skb->pkt_type = PACKET_HOST;
1671 pDevice->skb->protocol = htons(ETH_P_802_2);
1672 memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
1673 netif_rx(pDevice->skb);
1674 pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
1677 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
1679 union iwreq_data wrqu;
1680 memset(&wrqu, 0, sizeof(wrqu));
1681 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1682 PRINT_K("wireless_send_event--->SIOCGIWAP(disauthen)\n");
1683 wireless_send_event(pDevice->dev, SIOCGIWAP, &wrqu, NULL);
1685 #endif
1688 /* else, ignore it. TODO: IBSS authentication service
1689 would be implemented here */
1691 return;
1694 //2008-8-4 <add> by chester
1697 * Routine Description:
1698 * check if current channel is match ZoneType.
1699 *for USA:1~11;
1700 * Japan:1~13;
1701 * Europe:1~13
1702 * Return Value:
1703 * True:exceed;
1704 * False:normal case
1706 static bool
1707 ChannelExceedZoneType(
1708 PSDevice pDevice,
1709 unsigned char byCurrChannel
1712 bool exceed = false;
1714 switch (pDevice->byZoneType) {
1715 case 0x00: //USA:1~11
1716 if ((byCurrChannel < 1) || (byCurrChannel > 11))
1717 exceed = true;
1718 break;
1719 case 0x01: //Japan:1~13
1720 case 0x02: //Europe:1~13
1721 if ((byCurrChannel < 1) || (byCurrChannel > 13))
1722 exceed = true;
1723 break;
1724 default: //reserve for other zonetype
1725 break;
1728 return exceed;
1733 * Routine Description:
1734 * Handles and analysis incoming beacon frames.
1737 * Return Value:
1738 * None.
1742 static
1743 void
1744 s_vMgrRxBeacon(
1745 PSDevice pDevice,
1746 PSMgmtObject pMgmt,
1747 PSRxMgmtPacket pRxPacket,
1748 bool bInScan
1751 PKnownBSS pBSSList;
1752 WLAN_FR_BEACON sFrame;
1753 QWORD qwTSFOffset;
1754 bool bIsBSSIDEqual = false;
1755 bool bIsSSIDEqual = false;
1756 bool bTSFLargeDiff = false;
1757 bool bTSFOffsetPostive = false;
1758 bool bUpdateTSF = false;
1759 bool bIsAPBeacon = false;
1760 bool bIsChannelEqual = false;
1761 unsigned int uLocateByteIndex;
1762 unsigned char byTIMBitOn = 0;
1763 unsigned short wAIDNumber = 0;
1764 unsigned int uNodeIndex;
1765 QWORD qwTimestamp, qwLocalTSF;
1766 QWORD qwCurrTSF;
1767 unsigned short wStartIndex = 0;
1768 unsigned short wAIDIndex = 0;
1769 unsigned char byCurrChannel = pRxPacket->byRxChannel;
1770 ERPObject sERP;
1771 unsigned int uRateLen = WLAN_RATES_MAXLEN;
1772 bool bChannelHit = false;
1773 bool bUpdatePhyParameter = false;
1774 unsigned char byIEChannel = 0;
1776 memset(&sFrame, 0, sizeof(WLAN_FR_BEACON));
1777 sFrame.len = pRxPacket->cbMPDULen;
1778 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
1780 // decode the beacon frame
1781 vMgrDecodeBeacon(&sFrame);
1783 if ((sFrame.pwBeaconInterval == NULL) ||
1784 (sFrame.pwCapInfo == NULL) ||
1785 (sFrame.pSSID == NULL) ||
1786 (sFrame.pSuppRates == NULL)) {
1787 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
1788 return;
1791 if (sFrame.pDSParms != NULL) {
1792 if (byCurrChannel > CB_MAX_CHANNEL_24G) {
1793 // channel remapping to
1794 byIEChannel = get_channel_mapping(pDevice, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
1795 } else {
1796 byIEChannel = sFrame.pDSParms->byCurrChannel;
1798 if (byCurrChannel != byIEChannel) {
1799 // adjust channel info. bcs we rcv adjacent channel packets
1800 bChannelHit = false;
1801 byCurrChannel = byIEChannel;
1803 } else {
1804 // no DS channel info
1805 bChannelHit = true;
1807 //2008-0730-01<Add>by MikeLiu
1808 if (ChannelExceedZoneType(pDevice, byCurrChannel))
1809 return;
1811 if (sFrame.pERP != NULL) {
1812 sERP.byERP = sFrame.pERP->byContext;
1813 sERP.bERPExist = true;
1815 } else {
1816 sERP.bERPExist = false;
1817 sERP.byERP = 0;
1820 pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
1821 if (pBSSList == NULL) {
1822 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon/insert: RxChannel = : %d\n", byCurrChannel);
1823 BSSbInsertToBSSList((void *)pDevice,
1824 sFrame.pHdr->sA3.abyAddr3,
1825 *sFrame.pqwTimestamp,
1826 *sFrame.pwBeaconInterval,
1827 *sFrame.pwCapInfo,
1828 byCurrChannel,
1829 sFrame.pSSID,
1830 sFrame.pSuppRates,
1831 sFrame.pExtSuppRates,
1832 &sERP,
1833 sFrame.pRSN,
1834 sFrame.pRSNWPA,
1835 sFrame.pIE_Country,
1836 sFrame.pIE_Quiet,
1837 sFrame.len - WLAN_HDR_ADDR3_LEN,
1838 sFrame.pHdr->sA4.abyAddr4, // payload of beacon
1839 (void *)pRxPacket
1841 } else {
1842 BSSbUpdateToBSSList((void *)pDevice,
1843 *sFrame.pqwTimestamp,
1844 *sFrame.pwBeaconInterval,
1845 *sFrame.pwCapInfo,
1846 byCurrChannel,
1847 bChannelHit,
1848 sFrame.pSSID,
1849 sFrame.pSuppRates,
1850 sFrame.pExtSuppRates,
1851 &sERP,
1852 sFrame.pRSN,
1853 sFrame.pRSNWPA,
1854 sFrame.pIE_Country,
1855 sFrame.pIE_Quiet,
1856 pBSSList,
1857 sFrame.len - WLAN_HDR_ADDR3_LEN,
1858 sFrame.pHdr->sA4.abyAddr4, // payload of probresponse
1859 (void *)pRxPacket
1864 if (bInScan)
1865 return;
1867 if (byCurrChannel == (unsigned char)pMgmt->uCurrChannel)
1868 bIsChannelEqual = true;
1870 if (bIsChannelEqual && (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
1871 // if rx beacon without ERP field
1872 if (sERP.bERPExist) {
1873 if (WLAN_GET_ERP_USE_PROTECTION(sERP.byERP)) {
1874 pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1875 pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
1877 } else {
1878 pDevice->byERPFlag |= WLAN_SET_ERP_USE_PROTECTION(1);
1879 pDevice->wUseProtectCntDown = USE_PROTECT_PERIOD;
1882 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
1883 if (!WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo))
1884 pDevice->byERPFlag |= WLAN_SET_ERP_BARKER_MODE(1);
1885 if (!sERP.bERPExist)
1886 pDevice->byERPFlag |= WLAN_SET_ERP_NONERP_PRESENT(1);
1889 // set to MAC&BBP
1890 if (WLAN_GET_ERP_USE_PROTECTION(pDevice->byERPFlag)) {
1891 if (!pDevice->bProtectMode) {
1892 MACvEnableProtectMD(pDevice->PortOffset);
1893 pDevice->bProtectMode = true;
1898 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)
1899 return;
1901 // check if BSSID the same
1902 if (memcmp(sFrame.pHdr->sA3.abyAddr3,
1903 pMgmt->abyCurrBSSID,
1904 WLAN_BSSID_LEN) == 0) {
1905 bIsBSSIDEqual = true;
1907 // 2008-05-21 <add> by Richardtai
1908 pDevice->uCurrRSSI = pRxPacket->uRSSI;
1909 pDevice->byCurrSQ = pRxPacket->bySQ;
1911 if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
1912 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
1914 // check if SSID the same
1915 if (sFrame.pSSID->len == ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) {
1916 if (memcmp(sFrame.pSSID->abySSID,
1917 ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
1918 sFrame.pSSID->len
1919 ) == 0) {
1920 bIsSSIDEqual = true;
1924 if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo) &&
1925 bIsBSSIDEqual &&
1926 bIsSSIDEqual &&
1927 (pMgmt->eCurrMode == WMAC_MODE_ESS_STA) &&
1928 (pMgmt->eCurrState == WMAC_STATE_ASSOC)) {
1929 // add state check to prevent reconnect fail since we'll receive Beacon
1931 bIsAPBeacon = true;
1933 if (pBSSList != NULL) {
1934 // Compare PHY parameter setting
1935 if (pMgmt->wCurrCapInfo != pBSSList->wCapInfo) {
1936 bUpdatePhyParameter = true;
1937 pMgmt->wCurrCapInfo = pBSSList->wCapInfo;
1939 if (sFrame.pERP != NULL) {
1940 if ((sFrame.pERP->byElementID == WLAN_EID_ERP) &&
1941 (pMgmt->byERPContext != sFrame.pERP->byContext)) {
1942 bUpdatePhyParameter = true;
1943 pMgmt->byERPContext = sFrame.pERP->byContext;
1947 // Basic Rate Set may change dynamically
1949 if (pBSSList->eNetworkTypeInUse == PHY_TYPE_11B)
1950 uRateLen = WLAN_RATES_MAXLEN_11B;
1952 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abySuppRates,
1953 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
1954 uRateLen);
1955 pMgmt->abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pBSSList->abyExtSuppRates,
1956 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
1957 uRateLen);
1958 RATEvParseMaxRate((void *)pDevice,
1959 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
1960 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
1961 true,
1962 &(pMgmt->sNodeDBTable[0].wMaxBasicRate),
1963 &(pMgmt->sNodeDBTable[0].wMaxSuppRate),
1964 &(pMgmt->sNodeDBTable[0].wSuppRate),
1965 &(pMgmt->sNodeDBTable[0].byTopCCKBasicRate),
1966 &(pMgmt->sNodeDBTable[0].byTopOFDMBasicRate)
1968 if (bUpdatePhyParameter) {
1969 CARDbSetPhyParameter(pMgmt->pAdapter,
1970 pMgmt->eCurrentPHYMode,
1971 pMgmt->wCurrCapInfo,
1972 pMgmt->byERPContext,
1973 pMgmt->abyCurrSuppRates,
1974 pMgmt->abyCurrExtSuppRates
1977 if (sFrame.pIE_PowerConstraint != NULL) {
1978 CARDvSetPowerConstraint(pMgmt->pAdapter,
1979 (unsigned char) pBSSList->uChannel,
1980 sFrame.pIE_PowerConstraint->byPower
1983 if (sFrame.pIE_CHSW != NULL) {
1984 CARDbChannelSwitch(pMgmt->pAdapter,
1985 sFrame.pIE_CHSW->byMode,
1986 get_channel_mapping(pMgmt->pAdapter, sFrame.pIE_CHSW->byMode, pMgmt->eCurrentPHYMode),
1987 sFrame.pIE_CHSW->byCount
1990 } else if (!bIsChannelEqual) {
1991 set_channel(pMgmt->pAdapter, pBSSList->uChannel);
1996 // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2 \n");
1997 // check if CF field exists
1998 if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
1999 if (sFrame.pCFParms->wCFPDurRemaining > 0) {
2000 // TODO: deal with CFP period to set NAV
2004 HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
2005 LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
2006 HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF);
2007 LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF);
2009 // check if beacon TSF larger or small than our local TSF
2010 if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) {
2011 if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF))
2012 bTSFOffsetPostive = true;
2013 else
2014 bTSFOffsetPostive = false;
2015 } else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) {
2016 bTSFOffsetPostive = true;
2017 } else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
2018 bTSFOffsetPostive = false;
2021 if (bTSFOffsetPostive)
2022 qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
2023 else
2024 qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp));
2026 if (HIDWORD(qwTSFOffset) != 0 ||
2027 (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE)) {
2028 bTSFLargeDiff = true;
2031 // if infra mode
2032 if (bIsAPBeacon) {
2033 // Infra mode: Local TSF always follow AP's TSF if Difference huge.
2034 if (bTSFLargeDiff)
2035 bUpdateTSF = true;
2037 if (pDevice->bEnablePSMode && (sFrame.pTIM != NULL)) {
2038 // deal with DTIM, analysis TIM
2039 pMgmt->bMulticastTIM = WLAN_MGMT_IS_MULTICAST_TIM(sFrame.pTIM->byBitMapCtl) ? true : false;
2040 pMgmt->byDTIMCount = sFrame.pTIM->byDTIMCount;
2041 pMgmt->byDTIMPeriod = sFrame.pTIM->byDTIMPeriod;
2042 wAIDNumber = pMgmt->wCurrAID & ~(BIT14|BIT15);
2044 // check if AID in TIM field bit on
2045 // wStartIndex = N1
2046 wStartIndex = WLAN_MGMT_GET_TIM_OFFSET(sFrame.pTIM->byBitMapCtl) << 1;
2047 // AIDIndex = N2
2048 wAIDIndex = (wAIDNumber >> 3);
2049 if ((wAIDNumber > 0) && (wAIDIndex >= wStartIndex)) {
2050 uLocateByteIndex = wAIDIndex - wStartIndex;
2051 // len = byDTIMCount + byDTIMPeriod + byDTIMPeriod + byVirtBitMap[0~250]
2052 if (sFrame.pTIM->len >= (uLocateByteIndex + 4)) {
2053 byTIMBitOn = (0x01) << ((wAIDNumber) % 8);
2054 pMgmt->bInTIM = sFrame.pTIM->byVirtBitMap[uLocateByteIndex] & byTIMBitOn ? true : false;
2055 } else {
2056 pMgmt->bInTIM = false;
2058 } else {
2059 pMgmt->bInTIM = false;
2062 if (pMgmt->bInTIM ||
2063 (pMgmt->bMulticastTIM && (pMgmt->byDTIMCount == 0))) {
2064 pMgmt->bInTIMWake = true;
2065 // send out ps-poll packet
2067 if (pMgmt->bInTIM)
2068 PSvSendPSPOLL((PSDevice)pDevice);
2070 } else {
2071 pMgmt->bInTIMWake = false;
2072 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n");
2073 if (!pDevice->bPWBitOn) {
2074 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n");
2075 if (PSbSendNullPacket(pDevice))
2076 pDevice->bPWBitOn = true;
2078 if (PSbConsiderPowerDown(pDevice, false, false))
2079 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
2085 // if adhoc mode
2086 if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && !bIsAPBeacon && bIsChannelEqual) {
2087 if (bIsBSSIDEqual) {
2088 // Use sNodeDBTable[0].uInActiveCount as IBSS beacons received count.
2089 if (pMgmt->sNodeDBTable[0].uInActiveCount != 0)
2090 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2092 // adhoc mode:TSF updated only when beacon larger than local TSF
2093 if (bTSFLargeDiff && bTSFOffsetPostive &&
2094 (pMgmt->eCurrState == WMAC_STATE_JOINTED))
2095 bUpdateTSF = true;
2097 // During dpc, already in spinlocked.
2098 if (BSSDBbIsSTAInNodeDB(pMgmt, sFrame.pHdr->sA3.abyAddr2, &uNodeIndex)) {
2099 // Update the STA, (Technically the Beacons of all the IBSS nodes
2100 // should be identical, but that's not happening in practice.
2101 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2102 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2103 WLAN_RATES_MAXLEN_11B);
2104 RATEvParseMaxRate((void *)pDevice,
2105 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2106 NULL,
2107 true,
2108 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2109 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2110 &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2111 &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2112 &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2114 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2115 pMgmt->sNodeDBTable[uNodeIndex].bShortSlotTime = WLAN_GET_CAP_INFO_SHORTSLOTTIME(*sFrame.pwCapInfo);
2116 pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0;
2117 } else {
2118 // Todo, initial Node content
2119 BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex);
2121 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2122 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2123 WLAN_RATES_MAXLEN_11B);
2124 RATEvParseMaxRate((void *)pDevice,
2125 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2126 NULL,
2127 true,
2128 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
2129 &(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
2130 &(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
2131 &(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
2132 &(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
2135 memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, sFrame.pHdr->sA3.abyAddr2, WLAN_ADDR_LEN);
2136 pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble = WLAN_GET_CAP_INFO_SHORTPREAMBLE(*sFrame.pwCapInfo);
2137 pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate = pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
2138 #ifdef PLICE_DEBUG
2140 printk("s_vMgrRxBeacon:TxDataRate is %d,Index is %d\n", pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate, uNodeIndex);
2142 #endif
2145 // if other stations joined, indicate connection to upper layer..
2146 if (pMgmt->eCurrState == WMAC_STATE_STARTED) {
2147 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed] \n");
2148 pMgmt->eCurrState = WMAC_STATE_JOINTED;
2149 pDevice->bLinkPass = true;
2150 if (netif_queue_stopped(pDevice->dev))
2151 netif_wake_queue(pDevice->dev);
2153 pMgmt->sNodeDBTable[0].bActive = true;
2154 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
2157 } else if (bIsSSIDEqual) {
2158 // See other adhoc sta with the same SSID but BSSID is different.
2159 // adpot this vars only when TSF larger then us.
2160 if (bTSFLargeDiff && bTSFOffsetPostive) {
2161 // we don't support ATIM under adhoc mode
2162 // if (sFrame.pIBSSParms->wATIMWindow == 0) {
2163 // adpot this vars
2164 // TODO: check sFrame cap if privacy on, and support rate syn
2165 memcpy(pMgmt->abyCurrBSSID, sFrame.pHdr->sA3.abyAddr3, WLAN_BSSID_LEN);
2166 memcpy(pDevice->abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
2167 pMgmt->wCurrATIMWindow = cpu_to_le16(sFrame.pIBSSParms->wATIMWindow);
2168 pMgmt->wCurrBeaconPeriod = cpu_to_le16(*sFrame.pwBeaconInterval);
2169 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
2170 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2171 WLAN_RATES_MAXLEN_11B);
2172 // set HW beacon interval and re-synchronizing....
2173 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n");
2174 VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, pMgmt->wCurrBeaconPeriod);
2175 CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, qwLocalTSF);
2176 CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2177 // Turn off bssid filter to avoid filter others adhoc station which bssid is different.
2178 MACvWriteBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
2180 CARDbSetPhyParameter(pMgmt->pAdapter,
2181 pMgmt->eCurrentPHYMode,
2182 pMgmt->wCurrCapInfo,
2183 pMgmt->byERPContext,
2184 pMgmt->abyCurrSuppRates,
2185 pMgmt->abyCurrExtSuppRates);
2187 // Prepare beacon frame
2188 bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
2192 // endian issue ???
2193 // Update TSF
2194 if (bUpdateTSF) {
2195 CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2196 CARDbUpdateTSF(pDevice, pRxPacket->byRxRate, qwTimestamp, pRxPacket->qwLocalTSF);
2197 CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2198 CARDvUpdateNextTBTT(pDevice->PortOffset, qwTimestamp, pMgmt->wCurrBeaconPeriod);
2201 return;
2206 * Routine Description:
2207 * Instructs the hw to create a bss using the supplied
2208 * attributes. Note that this implementation only supports Ad-Hoc
2209 * BSS creation.
2212 * Return Value:
2213 * CMD_STATUS
2216 void
2217 vMgrCreateOwnIBSS(
2218 void *hDeviceContext,
2219 PCMD_STATUS pStatus
2222 PSDevice pDevice = (PSDevice)hDeviceContext;
2223 PSMgmtObject pMgmt = pDevice->pMgmt;
2224 unsigned short wMaxBasicRate;
2225 unsigned short wMaxSuppRate;
2226 unsigned char byTopCCKBasicRate;
2227 unsigned char byTopOFDMBasicRate;
2228 QWORD qwCurrTSF;
2229 unsigned int ii;
2230 unsigned char abyRATE[] = {0x82, 0x84, 0x8B, 0x96, 0x24, 0x30, 0x48, 0x6C, 0x0C, 0x12, 0x18, 0x60};
2231 unsigned char abyCCK_RATE[] = {0x82, 0x84, 0x8B, 0x96};
2232 unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2233 unsigned short wSuppRate;
2235 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n");
2237 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2238 if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) &&
2239 (pDevice->eEncryptionStatus != Ndis802_11Encryption2Enabled) &&
2240 (pDevice->eEncryptionStatus != Ndis802_11Encryption3Enabled)) {
2241 // encryption mode error
2242 *pStatus = CMD_STATUS_FAILURE;
2243 return;
2247 pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2248 pMgmt->abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
2250 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2251 pMgmt->eCurrentPHYMode = pMgmt->byAPBBType;
2252 } else {
2253 if (pDevice->byBBType == BB_TYPE_11G)
2254 pMgmt->eCurrentPHYMode = PHY_TYPE_11G;
2255 if (pDevice->byBBType == BB_TYPE_11B)
2256 pMgmt->eCurrentPHYMode = PHY_TYPE_11B;
2257 if (pDevice->byBBType == BB_TYPE_11A)
2258 pMgmt->eCurrentPHYMode = PHY_TYPE_11A;
2261 if (pMgmt->eCurrentPHYMode != PHY_TYPE_11A) {
2262 pMgmt->abyCurrSuppRates[1] = WLAN_RATES_MAXLEN_11B;
2263 pMgmt->abyCurrExtSuppRates[1] = 0;
2264 for (ii = 0; ii < 4; ii++)
2265 pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2266 } else {
2267 pMgmt->abyCurrSuppRates[1] = 8;
2268 pMgmt->abyCurrExtSuppRates[1] = 0;
2269 for (ii = 0; ii < 8; ii++)
2270 pMgmt->abyCurrSuppRates[2+ii] = abyRATE[ii];
2273 if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
2274 pMgmt->abyCurrSuppRates[1] = 8;
2275 pMgmt->abyCurrExtSuppRates[1] = 4;
2276 for (ii = 0; ii < 4; ii++)
2277 pMgmt->abyCurrSuppRates[2+ii] = abyCCK_RATE[ii];
2278 for (ii = 4; ii < 8; ii++)
2279 pMgmt->abyCurrSuppRates[2+ii] = abyOFDM_RATE[ii-4];
2280 for (ii = 0; ii < 4; ii++)
2281 pMgmt->abyCurrExtSuppRates[2+ii] = abyOFDM_RATE[ii+4];
2284 // Disable Protect Mode
2285 pDevice->bProtectMode = false;
2286 MACvDisableProtectMD(pDevice->PortOffset);
2288 pDevice->bBarkerPreambleMd = false;
2289 MACvDisableBarkerPreambleMd(pDevice->PortOffset);
2291 // Kyle Test 2003.11.04
2293 // set HW beacon interval
2294 if (pMgmt->wIBSSBeaconPeriod == 0)
2295 pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
2297 CARDbGetCurrentTSF(pDevice->PortOffset, &qwCurrTSF);
2298 // clear TSF counter
2299 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTRST);
2300 // enable TSF counter
2301 VNSvOutPortB(pDevice->PortOffset + MAC_REG_TFTCTL, TFTCTL_TSFCNTREN);
2303 // set Next TBTT
2304 CARDvSetFirstNextTBTT(pDevice->PortOffset, pMgmt->wIBSSBeaconPeriod);
2306 pMgmt->uIBSSChannel = pDevice->uChannel;
2308 if (pMgmt->uIBSSChannel == 0)
2309 pMgmt->uIBSSChannel = DEFAULT_IBSS_CHANNEL;
2311 // set basic rate
2313 RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2314 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates, true,
2315 &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2316 &byTopCCKBasicRate, &byTopOFDMBasicRate);
2318 if (pMgmt->eConfigMode == WMAC_CONFIG_AP)
2319 pMgmt->eCurrMode = WMAC_MODE_ESS_AP;
2321 if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) {
2322 memcpy(pMgmt->abyIBSSDFSOwner, pDevice->abyCurrentNetAddr, 6);
2323 pMgmt->byIBSSDFSRecovery = 10;
2324 pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2327 // Adopt pre-configured IBSS vars to current vars
2328 pMgmt->eCurrState = WMAC_STATE_STARTED;
2329 pMgmt->wCurrBeaconPeriod = pMgmt->wIBSSBeaconPeriod;
2330 pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2331 pMgmt->wCurrATIMWindow = pMgmt->wIBSSATIMWindow;
2332 MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
2333 pDevice->uCurrRSSI = 0;
2334 pDevice->byCurrSQ = 0;
2335 memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2336 memcpy(pMgmt->abyCurrSSID,
2337 pMgmt->abyDesireSSID,
2338 ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->len + WLAN_IEHDR_LEN
2341 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2342 // AP mode BSSID = MAC addr
2343 memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
2344 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "AP beacon created BSSID:%pM\n",
2345 pMgmt->abyCurrBSSID);
2348 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2349 // BSSID selected must be randomized as spec 11.1.3
2350 pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF) & 0x000000ff);
2351 pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0000ff00) >> 8);
2352 pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00ff0000) >> 16);
2353 pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00000ff0) >> 4);
2354 pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF) & 0x000ff000) >> 12);
2355 pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0ff00000) >> 20);
2356 pMgmt->abyCurrBSSID[5] ^= pMgmt->abyMACAddr[0];
2357 pMgmt->abyCurrBSSID[4] ^= pMgmt->abyMACAddr[1];
2358 pMgmt->abyCurrBSSID[3] ^= pMgmt->abyMACAddr[2];
2359 pMgmt->abyCurrBSSID[2] ^= pMgmt->abyMACAddr[3];
2360 pMgmt->abyCurrBSSID[1] ^= pMgmt->abyMACAddr[4];
2361 pMgmt->abyCurrBSSID[0] ^= pMgmt->abyMACAddr[5];
2362 pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP;
2363 pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL;
2365 DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Adhoc beacon created bssid:%pM\n",
2366 pMgmt->abyCurrBSSID);
2369 // Set Capability Info
2370 pMgmt->wCurrCapInfo = 0;
2372 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2373 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
2374 pMgmt->byDTIMPeriod = DEFAULT_DTIM_PERIOD;
2375 pMgmt->byDTIMCount = pMgmt->byDTIMPeriod - 1;
2378 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA)
2379 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_IBSS(1);
2381 if (pDevice->bEncryptionEnable) {
2382 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
2383 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2384 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2385 pMgmt->byCSSPK = KEY_CTL_CCMP;
2386 pMgmt->byCSSGK = KEY_CTL_CCMP;
2387 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2388 pMgmt->byCSSPK = KEY_CTL_TKIP;
2389 pMgmt->byCSSGK = KEY_CTL_TKIP;
2390 } else {
2391 pMgmt->byCSSPK = KEY_CTL_NONE;
2392 pMgmt->byCSSGK = KEY_CTL_WEP;
2394 } else {
2395 pMgmt->byCSSPK = KEY_CTL_WEP;
2396 pMgmt->byCSSGK = KEY_CTL_WEP;
2400 pMgmt->byERPContext = 0;
2402 if (pMgmt->eConfigMode == WMAC_CONFIG_AP) {
2403 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_AP);
2404 } else {
2405 CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_ADHOC);
2408 CARDbSetPhyParameter(pMgmt->pAdapter,
2409 pMgmt->eCurrentPHYMode,
2410 pMgmt->wCurrCapInfo,
2411 pMgmt->byERPContext,
2412 pMgmt->abyCurrSuppRates,
2413 pMgmt->abyCurrExtSuppRates
2416 CARDbSetBeaconPeriod(pMgmt->pAdapter, pMgmt->wIBSSBeaconPeriod);
2417 // set channel and clear NAV
2418 set_channel(pMgmt->pAdapter, pMgmt->uIBSSChannel);
2419 pMgmt->uCurrChannel = pMgmt->uIBSSChannel;
2421 if (CARDbIsShortPreamble(pMgmt->pAdapter))
2422 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
2423 else
2424 pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SHORTPREAMBLE(1));
2426 if (pMgmt->b11hEnable &&
2427 (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
2428 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
2429 } else {
2430 pMgmt->wCurrCapInfo &= (~WLAN_SET_CAP_INFO_SPECTRUMMNG(1));
2433 pMgmt->eCurrState = WMAC_STATE_STARTED;
2434 // Prepare beacon to send
2435 if (bMgrPrepareBeaconToSend((void *)pDevice, pMgmt))
2436 *pStatus = CMD_STATUS_SUCCESS;
2438 return;
2443 * Routine Description:
2444 * Instructs wmac to join a bss using the supplied attributes.
2445 * The arguments may the BSSID or SSID and the rest of the
2446 * attributes are obtained from the scan result of known bss list.
2449 * Return Value:
2450 * None.
2454 void
2455 vMgrJoinBSSBegin(
2456 void *hDeviceContext,
2457 PCMD_STATUS pStatus
2460 PSDevice pDevice = (PSDevice)hDeviceContext;
2461 PSMgmtObject pMgmt = pDevice->pMgmt;
2462 PKnownBSS pCurr = NULL;
2463 unsigned int ii, uu;
2464 PWLAN_IE_SUPP_RATES pItemRates = NULL;
2465 PWLAN_IE_SUPP_RATES pItemExtRates = NULL;
2466 PWLAN_IE_SSID pItemSSID;
2467 unsigned int uRateLen = WLAN_RATES_MAXLEN;
2468 unsigned short wMaxBasicRate = RATE_1M;
2469 unsigned short wMaxSuppRate = RATE_1M;
2470 unsigned short wSuppRate;
2471 unsigned char byTopCCKBasicRate = RATE_1M;
2472 unsigned char byTopOFDMBasicRate = RATE_1M;
2474 for (ii = 0; ii < MAX_BSS_NUM; ii++) {
2475 if (pMgmt->sBSSList[ii].bActive)
2476 break;
2479 if (ii == MAX_BSS_NUM) {
2480 *pStatus = CMD_STATUS_RESOURCES;
2481 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
2482 return;
2485 // Search known BSS list for prefer BSSID or SSID
2487 pCurr = BSSpSearchBSSList(pDevice,
2488 pMgmt->abyDesireBSSID,
2489 pMgmt->abyDesireSSID,
2490 pMgmt->eConfigPHYMode
2493 if (pCurr == NULL) {
2494 *pStatus = CMD_STATUS_RESOURCES;
2495 pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
2496 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
2497 return;
2500 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
2501 if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))) {
2502 if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)) {
2503 // patch for CISCO migration mode
2506 #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
2507 Encyption_Rebuild(pDevice, pCurr);
2508 #endif
2509 // Infrastructure BSS
2510 s_vMgrSynchBSS(pDevice,
2511 WMAC_MODE_ESS_STA,
2512 pCurr,
2513 pStatus
2516 if (*pStatus == CMD_STATUS_SUCCESS) {
2517 // Adopt this BSS state vars in Mgmt Object
2518 pMgmt->uCurrChannel = pCurr->uChannel;
2520 memset(pMgmt->abyCurrSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2521 memset(pMgmt->abyCurrExtSuppRates, 0 , WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
2523 if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B)
2524 uRateLen = WLAN_RATES_MAXLEN_11B;
2526 pItemRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates;
2527 pItemExtRates = (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates;
2529 // Parse Support Rate IE
2530 pItemRates->byElementID = WLAN_EID_SUPP_RATES;
2531 pItemRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2532 pItemRates,
2533 uRateLen);
2535 // Parse Extension Support Rate IE
2536 pItemExtRates->byElementID = WLAN_EID_EXTSUPP_RATES;
2537 pItemExtRates->len = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abyExtSuppRates,
2538 pItemExtRates,
2539 uRateLen);
2540 // Stuffing Rate IE
2541 if ((pItemExtRates->len > 0) && (pItemRates->len < 8)) {
2542 for (ii = 0; ii < (unsigned int)(8 - pItemRates->len);) {
2543 pItemRates->abyRates[pItemRates->len + ii] = pItemExtRates->abyRates[ii];
2544 ii++;
2545 if (pItemExtRates->len <= ii)
2546 break;
2548 pItemRates->len += (unsigned char)ii;
2549 if (pItemExtRates->len - ii > 0) {
2550 pItemExtRates->len -= (unsigned char)ii;
2551 for (uu = 0; uu < pItemExtRates->len; uu++)
2552 pItemExtRates->abyRates[uu] = pItemExtRates->abyRates[uu + ii];
2553 } else {
2554 pItemExtRates->len = 0;
2558 RATEvParseMaxRate((void *)pDevice, pItemRates, pItemExtRates, true,
2559 &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2560 &byTopCCKBasicRate, &byTopOFDMBasicRate);
2562 // TODO: deal with if wCapInfo the privacy is on, but station WEP is off
2563 // TODO: deal with if wCapInfo the PS-Pollable is on.
2564 pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2565 memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2566 memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2567 memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
2569 pMgmt->eCurrMode = WMAC_MODE_ESS_STA;
2571 pMgmt->eCurrState = WMAC_STATE_JOINTED;
2573 // Add current BSS to Candidate list
2574 // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
2575 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) {
2576 bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
2577 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult);
2578 if (!bResult) {
2579 vFlush_PMKID_Candidate((void *)pDevice);
2580 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n");
2581 bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj);
2585 // Preamble type auto-switch: if AP can receive short-preamble cap,
2586 // we can turn on too.
2588 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join ESS\n");
2590 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n");
2591 } else {
2592 pMgmt->eCurrState = WMAC_STATE_IDLE;
2595 } else {
2596 // ad-hoc mode BSS
2597 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
2598 if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled) {
2599 if (!WPA_SearchRSN(0, WPA_TKIP, pCurr)) {
2600 // encryption mode error
2601 pMgmt->eCurrState = WMAC_STATE_IDLE;
2602 return;
2604 } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) {
2605 if (!WPA_SearchRSN(0, WPA_AESCCMP, pCurr)) {
2606 // encryption mode error
2607 pMgmt->eCurrState = WMAC_STATE_IDLE;
2608 return;
2610 } else {
2611 // encryption mode error
2612 pMgmt->eCurrState = WMAC_STATE_IDLE;
2613 return;
2617 s_vMgrSynchBSS(pDevice,
2618 WMAC_MODE_IBSS_STA,
2619 pCurr,
2620 pStatus
2623 if (*pStatus == CMD_STATUS_SUCCESS) {
2624 // Adopt this BSS state vars in Mgmt Object
2625 // TODO: check if CapInfo privacy on, but we don't..
2626 pMgmt->uCurrChannel = pCurr->uChannel;
2628 // Parse Support Rate IE
2629 pMgmt->abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
2630 pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)pCurr->abySuppRates,
2631 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2632 WLAN_RATES_MAXLEN_11B);
2633 // set basic rate
2634 RATEvParseMaxRate((void *)pDevice, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
2635 NULL, true, &wMaxBasicRate, &wMaxSuppRate, &wSuppRate,
2636 &byTopCCKBasicRate, &byTopOFDMBasicRate);
2638 pMgmt->wCurrCapInfo = pCurr->wCapInfo;
2639 pMgmt->wCurrBeaconPeriod = pCurr->wBeaconInterval;
2640 memset(pMgmt->abyCurrSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2641 memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN);
2642 memcpy(pMgmt->abyCurrSSID, pCurr->abySSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN);
2643 MACvWriteATIMW(pDevice->PortOffset, pMgmt->wCurrATIMWindow);
2644 pMgmt->eCurrMode = WMAC_MODE_IBSS_STA;
2646 pMgmt->eCurrState = WMAC_STATE_STARTED;
2648 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join IBSS ok:%pM\n",
2649 pMgmt->abyCurrBSSID);
2650 // Preamble type auto-switch: if AP can receive short-preamble cap,
2651 // and if registry setting is short preamble we can turn on too.
2653 // Prepare beacon
2654 bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
2655 } else {
2656 pMgmt->eCurrState = WMAC_STATE_IDLE;
2659 return;
2664 * Routine Description:
2665 * Set HW to synchronize a specific BSS from known BSS list.
2668 * Return Value:
2669 * PCM_STATUS
2672 static
2673 void
2674 s_vMgrSynchBSS(
2675 PSDevice pDevice,
2676 unsigned int uBSSMode,
2677 PKnownBSS pCurr,
2678 PCMD_STATUS pStatus
2681 CARD_PHY_TYPE ePhyType = PHY_TYPE_11B;
2682 PSMgmtObject pMgmt = pDevice->pMgmt;
2684 //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M
2685 unsigned char abyCurrSuppRatesG[] = {WLAN_EID_SUPP_RATES, 8, 0x02, 0x04, 0x0B, 0x16, 0x24, 0x30, 0x48, 0x6C};
2686 unsigned char abyCurrExtSuppRatesG[] = {WLAN_EID_EXTSUPP_RATES, 4, 0x0C, 0x12, 0x18, 0x60};
2687 //6M, 9M, 12M, 48M
2688 unsigned char abyCurrSuppRatesA[] = {WLAN_EID_SUPP_RATES, 8, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C};
2689 unsigned char abyCurrSuppRatesB[] = {WLAN_EID_SUPP_RATES, 4, 0x02, 0x04, 0x0B, 0x16};
2691 *pStatus = CMD_STATUS_FAILURE;
2693 if (!s_bCipherMatch(pCurr,
2694 pDevice->eEncryptionStatus,
2695 &(pMgmt->byCSSPK),
2696 &(pMgmt->byCSSGK))) {
2697 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n");
2698 return;
2701 pMgmt->pCurrBSS = pCurr;
2703 // if previous mode is IBSS.
2704 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
2705 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_BCNDMACTL, BEACON_READY);
2706 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX);
2709 // Init the BSS informations
2710 pDevice->bCCK = true;
2711 pDevice->bProtectMode = false;
2712 MACvDisableProtectMD(pDevice->PortOffset);
2713 pDevice->bBarkerPreambleMd = false;
2714 MACvDisableBarkerPreambleMd(pDevice->PortOffset);
2715 pDevice->bNonERPPresent = false;
2716 pDevice->byPreambleType = 0;
2717 pDevice->wBasicRate = 0;
2718 // Set Basic Rate
2719 CARDbAddBasicRate((void *)pDevice, RATE_1M);
2720 // calculate TSF offset
2721 // TSF Offset = Received Timestamp TSF - Marked Local's TSF
2722 CARDbUpdateTSF(pDevice, pCurr->byRxRate, pCurr->qwBSSTimestamp, pCurr->qwLocalTSF);
2724 CARDbSetBeaconPeriod(pDevice, pCurr->wBeaconInterval);
2726 // set Next TBTT
2727 // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval
2728 CARDvSetFirstNextTBTT(pDevice->PortOffset, pCurr->wBeaconInterval);
2730 // set BSSID
2731 MACvWriteBSSIDAddress(pDevice->PortOffset, pCurr->abyBSSID);
2733 MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID);
2735 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = "
2736 "%pM\n", pMgmt->abyCurrBSSID);
2738 if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) {
2739 if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) ||
2740 (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2741 ePhyType = PHY_TYPE_11A;
2742 } else {
2743 return;
2745 } else if (pCurr->eNetworkTypeInUse == PHY_TYPE_11B) {
2746 if ((pMgmt->eConfigPHYMode == PHY_TYPE_11B) ||
2747 (pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
2748 (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2749 ePhyType = PHY_TYPE_11B;
2750 } else {
2751 return;
2753 } else {
2754 if ((pMgmt->eConfigPHYMode == PHY_TYPE_11G) ||
2755 (pMgmt->eConfigPHYMode == PHY_TYPE_AUTO)) {
2756 ePhyType = PHY_TYPE_11G;
2757 } else if (pMgmt->eConfigPHYMode == PHY_TYPE_11B) {
2758 ePhyType = PHY_TYPE_11B;
2759 } else {
2760 return;
2764 if (ePhyType == PHY_TYPE_11A) {
2765 memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
2766 pMgmt->abyCurrExtSuppRates[1] = 0;
2767 } else if (ePhyType == PHY_TYPE_11B) {
2768 memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesB[0], sizeof(abyCurrSuppRatesB));
2769 pMgmt->abyCurrExtSuppRates[1] = 0;
2770 } else {
2771 memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesG[0], sizeof(abyCurrSuppRatesG));
2772 memcpy(pMgmt->abyCurrExtSuppRates, &abyCurrExtSuppRatesG[0], sizeof(abyCurrExtSuppRatesG));
2775 if (WLAN_GET_CAP_INFO_ESS(pCurr->wCapInfo)) {
2776 CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_INFRASTRUCTURE);
2777 // Add current BSS to Candidate list
2778 // This should only works for WPA2 BSS, and WPA2 BSS check must be done before.
2779 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)
2780 CARDbAdd_PMKID_Candidate(pMgmt->pAdapter, pMgmt->abyCurrBSSID, pCurr->sRSNCapObj.bRSNCapExist, pCurr->sRSNCapObj.wRSNCap);
2781 } else {
2782 CARDbSetBSSID(pMgmt->pAdapter, pCurr->abyBSSID, OP_MODE_ADHOC);
2785 if (!CARDbSetPhyParameter(pMgmt->pAdapter,
2786 ePhyType,
2787 pCurr->wCapInfo,
2788 pCurr->sERP.byERP,
2789 pMgmt->abyCurrSuppRates,
2790 pMgmt->abyCurrExtSuppRates)) {
2791 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType);
2792 return;
2794 // set channel and clear NAV
2795 if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) {
2796 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", pCurr->uChannel);
2797 return;
2800 pMgmt->uCurrChannel = pCurr->uChannel;
2801 pMgmt->eCurrentPHYMode = ePhyType;
2802 pMgmt->byERPContext = pCurr->sERP.byERP;
2803 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel);
2805 *pStatus = CMD_STATUS_SUCCESS;
2807 return;
2810 //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption
2811 // ,need reset eAuthenMode and eEncryptionStatus
2812 static void Encyption_Rebuild(
2813 PSDevice pDevice,
2814 PKnownBSS pCurr
2817 PSMgmtObject pMgmt = &(pDevice->sMgmtObj);
2819 if ((pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || //networkmanager 0.7.0 does not give the pairwise-key selection,
2820 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) { // so we need re-select it according to real pairwise-key info.
2821 if (pCurr->bWPAValid) { //WPA-PSK
2822 pMgmt->eAuthenMode = WMAC_AUTH_WPAPSK;
2823 if (pCurr->abyPKType[0] == WPA_TKIP) {
2824 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP
2825 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-TKIP]\n");
2826 } else if (pCurr->abyPKType[0] == WPA_AESCCMP) {
2827 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES
2828 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPAPSK-AES]\n");
2830 } else if (pCurr->bWPA2Valid) { //WPA2-PSK
2831 pMgmt->eAuthenMode = WMAC_AUTH_WPA2PSK;
2832 if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_TKIP) {
2833 pDevice->eEncryptionStatus = Ndis802_11Encryption2Enabled; //TKIP
2834 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-TKIP]\n");
2835 } else if (pCurr->abyCSSPK[0] == WLAN_11i_CSS_CCMP) {
2836 pDevice->eEncryptionStatus = Ndis802_11Encryption3Enabled; //AES
2837 PRINT_K("Encyption_Rebuild--->ssid reset config to [WPA2PSK-AES]\n");
2842 return;
2847 * Routine Description:
2848 * Format TIM field
2851 * Return Value:
2852 * void
2856 static
2857 void
2858 s_vMgrFormatTIM(
2859 PSMgmtObject pMgmt,
2860 PWLAN_IE_TIM pTIM
2863 unsigned char byMask[8] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80};
2864 unsigned char byMap;
2865 unsigned int ii, jj;
2866 bool bStartFound = false;
2867 bool bMulticast = false;
2868 unsigned short wStartIndex = 0;
2869 unsigned short wEndIndex = 0;
2871 // Find size of partial virtual bitmap
2872 for (ii = 0; ii < (MAX_NODE_NUM + 1); ii++) {
2873 byMap = pMgmt->abyPSTxMap[ii];
2874 if (!ii) {
2875 // Mask out the broadcast bit which is indicated separately.
2876 bMulticast = (byMap & byMask[0]) != 0;
2877 if (bMulticast)
2878 pMgmt->sNodeDBTable[0].bRxPSPoll = true;
2880 byMap = 0;
2882 if (byMap) {
2883 if (!bStartFound) {
2884 bStartFound = true;
2885 wStartIndex = ii;
2887 wEndIndex = ii;
2891 // Round start index down to nearest even number
2892 wStartIndex &= ~BIT0;
2894 // Round end index up to nearest even number
2895 wEndIndex = ((wEndIndex + 1) & ~BIT0);
2897 // Size of element payload
2899 pTIM->len = 3 + (wEndIndex - wStartIndex) + 1;
2901 // Fill in the Fixed parts of the TIM
2902 pTIM->byDTIMCount = pMgmt->byDTIMCount;
2903 pTIM->byDTIMPeriod = pMgmt->byDTIMPeriod;
2904 pTIM->byBitMapCtl = (bMulticast ? TIM_MULTICAST_MASK : 0) |
2905 (((wStartIndex >> 1) << 1) & TIM_BITMAPOFFSET_MASK);
2907 // Append variable part of TIM
2909 for (ii = wStartIndex, jj = 0; ii <= wEndIndex; ii++, jj++)
2910 pTIM->byVirtBitMap[jj] = pMgmt->abyPSTxMap[ii];
2912 // Aid = 0 don't used.
2913 pTIM->byVirtBitMap[0] &= ~BIT0;
2918 * Routine Description:
2919 * Constructs an Beacon frame(Ad-hoc mode)
2922 * Return Value:
2923 * PTR to frame; or NULL on allocation failure
2927 static
2928 PSTxMgmtPacket
2929 s_MgrMakeBeacon(
2930 PSDevice pDevice,
2931 PSMgmtObject pMgmt,
2932 unsigned short wCurrCapInfo,
2933 unsigned short wCurrBeaconPeriod,
2934 unsigned int uCurrChannel,
2935 unsigned short wCurrATIMWinodw,
2936 PWLAN_IE_SSID pCurrSSID,
2937 unsigned char *pCurrBSSID,
2938 PWLAN_IE_SUPP_RATES pCurrSuppRates,
2939 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
2942 PSTxMgmtPacket pTxPacket = NULL;
2943 WLAN_FR_BEACON sFrame;
2944 unsigned char abyBroadcastAddr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2945 unsigned char *pbyBuffer;
2946 unsigned int uLength = 0;
2947 PWLAN_IE_IBSS_DFS pIBSSDFS = NULL;
2948 unsigned int ii;
2950 // prepare beacon frame
2951 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
2952 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_BEACON_FR_MAXLEN);
2953 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
2954 // Setup the sFrame structure.
2955 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
2956 sFrame.len = WLAN_BEACON_FR_MAXLEN;
2957 vMgrEncodeBeacon(&sFrame);
2958 // Setup the header
2959 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
2961 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
2962 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_BEACON)
2965 if (pDevice->bEnablePSMode)
2966 sFrame.pHdr->sA3.wFrameCtl |= cpu_to_le16((unsigned short)WLAN_SET_FC_PWRMGT(1));
2968 memcpy(sFrame.pHdr->sA3.abyAddr1, abyBroadcastAddr, WLAN_ADDR_LEN);
2969 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
2970 memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
2971 *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
2972 *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
2973 // Copy SSID
2974 sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
2975 sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
2976 memcpy(sFrame.pSSID,
2977 pCurrSSID,
2978 ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
2980 // Copy the rate set
2981 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
2982 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
2983 memcpy(sFrame.pSuppRates,
2984 pCurrSuppRates,
2985 ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
2987 // DS parameter
2988 if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
2989 sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
2990 sFrame.len += (1) + WLAN_IEHDR_LEN;
2991 sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
2992 sFrame.pDSParms->len = 1;
2993 sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
2995 // TIM field
2996 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
2997 sFrame.pTIM = (PWLAN_IE_TIM)(sFrame.pBuf + sFrame.len);
2998 sFrame.pTIM->byElementID = WLAN_EID_TIM;
2999 s_vMgrFormatTIM(pMgmt, sFrame.pTIM);
3000 sFrame.len += (WLAN_IEHDR_LEN + sFrame.pTIM->len);
3003 if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) {
3004 // IBSS parameter
3005 sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3006 sFrame.len += (2) + WLAN_IEHDR_LEN;
3007 sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3008 sFrame.pIBSSParms->len = 2;
3009 sFrame.pIBSSParms->wATIMWindow = wCurrATIMWinodw;
3010 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3011 /* RSN parameter */
3012 sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3013 sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3014 sFrame.pRSNWPA->len = 12;
3015 sFrame.pRSNWPA->abyOUI[0] = 0x00;
3016 sFrame.pRSNWPA->abyOUI[1] = 0x50;
3017 sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3018 sFrame.pRSNWPA->abyOUI[3] = 0x01;
3019 sFrame.pRSNWPA->wVersion = 1;
3020 sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3021 sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3022 sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3023 if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled)
3024 sFrame.pRSNWPA->abyMulticast[3] = 0x04;//AES
3025 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption2Enabled)
3026 sFrame.pRSNWPA->abyMulticast[3] = 0x02;//TKIP
3027 else if (pDevice->eEncryptionStatus == Ndis802_11Encryption1Enabled)
3028 sFrame.pRSNWPA->abyMulticast[3] = 0x01;//WEP40
3029 else
3030 sFrame.pRSNWPA->abyMulticast[3] = 0x00;//NONE
3032 // Pairwise Key Cipher Suite
3033 sFrame.pRSNWPA->wPKCount = 0;
3034 // Auth Key Management Suite
3035 *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0;
3036 sFrame.pRSNWPA->len += 2;
3038 // RSN Capabilities
3039 *((unsigned short *)(sFrame.pBuf + sFrame.len + sFrame.pRSNWPA->len)) = 0;
3040 sFrame.pRSNWPA->len += 2;
3041 sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3045 if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
3046 // Country IE
3047 pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
3048 set_country_IE(pMgmt->pAdapter, pbyBuffer);
3049 set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
3050 uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
3051 pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
3052 // Power Constrain IE
3053 ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
3054 ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
3055 ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
3056 pbyBuffer += (1) + WLAN_IEHDR_LEN;
3057 uLength += (1) + WLAN_IEHDR_LEN;
3058 if (pMgmt->bSwitchChannel) {
3059 // Channel Switch IE
3060 ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
3061 ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
3062 ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
3063 ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
3064 ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
3065 pbyBuffer += (3) + WLAN_IEHDR_LEN;
3066 uLength += (3) + WLAN_IEHDR_LEN;
3068 // TPC report
3069 ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
3070 ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
3071 ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
3072 ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
3073 pbyBuffer += (2) + WLAN_IEHDR_LEN;
3074 uLength += (2) + WLAN_IEHDR_LEN;
3075 // IBSS DFS
3076 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3077 pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
3078 pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
3079 pIBSSDFS->len = 7;
3080 memcpy(pIBSSDFS->abyDFSOwner,
3081 pMgmt->abyIBSSDFSOwner,
3083 pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
3084 pbyBuffer += (7) + WLAN_IEHDR_LEN;
3085 uLength += (7) + WLAN_IEHDR_LEN;
3086 for (ii = CB_MAX_CHANNEL_24G+1; ii <= CB_MAX_CHANNEL; ii++) {
3087 if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) {
3088 pbyBuffer += 2;
3089 uLength += 2;
3090 pIBSSDFS->len += 2;
3094 sFrame.len += uLength;
3097 if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
3098 sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3099 sFrame.len += 1 + WLAN_IEHDR_LEN;
3100 sFrame.pERP->byElementID = WLAN_EID_ERP;
3101 sFrame.pERP->len = 1;
3102 sFrame.pERP->byContext = 0;
3103 if (pDevice->bProtectMode)
3104 sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3105 if (pDevice->bNonERPPresent)
3106 sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3107 if (pDevice->bBarkerPreambleMd)
3108 sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3110 if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3111 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3112 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3113 memcpy(sFrame.pExtSuppRates,
3114 pCurrExtSuppRates,
3115 ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3118 // hostapd wpa/wpa2 IE
3119 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) {
3120 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3121 if (pMgmt->wWPAIELen != 0) {
3122 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3123 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3124 sFrame.len += pMgmt->wWPAIELen;
3129 /* Adjust the length fields */
3130 pTxPacket->cbMPDULen = sFrame.len;
3131 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3133 return pTxPacket;
3138 * Routine Description:
3139 * Constructs an Prob-response frame
3142 * Return Value:
3143 * PTR to frame; or NULL on allocation failure
3147 PSTxMgmtPacket
3148 s_MgrMakeProbeResponse(
3149 PSDevice pDevice,
3150 PSMgmtObject pMgmt,
3151 unsigned short wCurrCapInfo,
3152 unsigned short wCurrBeaconPeriod,
3153 unsigned int uCurrChannel,
3154 unsigned short wCurrATIMWinodw,
3155 unsigned char *pDstAddr,
3156 PWLAN_IE_SSID pCurrSSID,
3157 unsigned char *pCurrBSSID,
3158 PWLAN_IE_SUPP_RATES pCurrSuppRates,
3159 PWLAN_IE_SUPP_RATES pCurrExtSuppRates,
3160 unsigned char byPHYType
3163 PSTxMgmtPacket pTxPacket = NULL;
3164 WLAN_FR_PROBERESP sFrame;
3165 unsigned char *pbyBuffer;
3166 unsigned int uLength = 0;
3167 PWLAN_IE_IBSS_DFS pIBSSDFS = NULL;
3168 unsigned int ii;
3170 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3171 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_PROBERESP_FR_MAXLEN);
3172 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3173 // Setup the sFrame structure.
3174 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3175 sFrame.len = WLAN_PROBERESP_FR_MAXLEN;
3176 vMgrEncodeProbeResponse(&sFrame);
3177 // Setup the header
3178 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3180 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3181 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_PROBERESP)
3183 memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3184 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3185 memcpy(sFrame.pHdr->sA3.abyAddr3, pCurrBSSID, WLAN_BSSID_LEN);
3186 *sFrame.pwBeaconInterval = cpu_to_le16(wCurrBeaconPeriod);
3187 *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3189 if (byPHYType == BB_TYPE_11B)
3190 *sFrame.pwCapInfo &= cpu_to_le16((unsigned short)~(WLAN_SET_CAP_INFO_SHORTSLOTTIME(1)));
3192 // Copy SSID
3193 sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3194 sFrame.len += ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len + WLAN_IEHDR_LEN;
3195 memcpy(sFrame.pSSID,
3196 pCurrSSID,
3197 ((PWLAN_IE_SSID)pCurrSSID)->len + WLAN_IEHDR_LEN
3199 // Copy the rate set
3200 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3202 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3203 memcpy(sFrame.pSuppRates,
3204 pCurrSuppRates,
3205 ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3208 // DS parameter
3209 if (pDevice->eCurrentPHYType != PHY_TYPE_11A) {
3210 sFrame.pDSParms = (PWLAN_IE_DS_PARMS)(sFrame.pBuf + sFrame.len);
3211 sFrame.len += (1) + WLAN_IEHDR_LEN;
3212 sFrame.pDSParms->byElementID = WLAN_EID_DS_PARMS;
3213 sFrame.pDSParms->len = 1;
3214 sFrame.pDSParms->byCurrChannel = (unsigned char)uCurrChannel;
3217 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3218 // IBSS parameter
3219 sFrame.pIBSSParms = (PWLAN_IE_IBSS_PARMS)(sFrame.pBuf + sFrame.len);
3220 sFrame.len += (2) + WLAN_IEHDR_LEN;
3221 sFrame.pIBSSParms->byElementID = WLAN_EID_IBSS_PARMS;
3222 sFrame.pIBSSParms->len = 2;
3223 sFrame.pIBSSParms->wATIMWindow = 0;
3225 if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
3226 sFrame.pERP = (PWLAN_IE_ERP)(sFrame.pBuf + sFrame.len);
3227 sFrame.len += 1 + WLAN_IEHDR_LEN;
3228 sFrame.pERP->byElementID = WLAN_EID_ERP;
3229 sFrame.pERP->len = 1;
3230 sFrame.pERP->byContext = 0;
3231 if (pDevice->bProtectMode)
3232 sFrame.pERP->byContext |= WLAN_EID_ERP_USE_PROTECTION;
3233 if (pDevice->bNonERPPresent)
3234 sFrame.pERP->byContext |= WLAN_EID_ERP_NONERP_PRESENT;
3235 if (pDevice->bBarkerPreambleMd)
3236 sFrame.pERP->byContext |= WLAN_EID_ERP_BARKER_MODE;
3239 if (pMgmt->b11hEnable && (pMgmt->eCurrentPHYMode == PHY_TYPE_11A)) {
3240 // Country IE
3241 pbyBuffer = (unsigned char *)(sFrame.pBuf + sFrame.len);
3242 set_country_IE(pMgmt->pAdapter, pbyBuffer);
3243 set_country_info(pMgmt->pAdapter, PHY_TYPE_11A, pbyBuffer);
3244 uLength += ((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN;
3245 pbyBuffer += (((PWLAN_IE_COUNTRY) pbyBuffer)->len + WLAN_IEHDR_LEN);
3246 // Power Constrain IE
3247 ((PWLAN_IE_PW_CONST) pbyBuffer)->byElementID = WLAN_EID_PWR_CONSTRAINT;
3248 ((PWLAN_IE_PW_CONST) pbyBuffer)->len = 1;
3249 ((PWLAN_IE_PW_CONST) pbyBuffer)->byPower = 0;
3250 pbyBuffer += (1) + WLAN_IEHDR_LEN;
3251 uLength += (1) + WLAN_IEHDR_LEN;
3252 if (pMgmt->bSwitchChannel) {
3253 // Channel Switch IE
3254 ((PWLAN_IE_CH_SW) pbyBuffer)->byElementID = WLAN_EID_CH_SWITCH;
3255 ((PWLAN_IE_CH_SW) pbyBuffer)->len = 3;
3256 ((PWLAN_IE_CH_SW) pbyBuffer)->byMode = 1;
3257 ((PWLAN_IE_CH_SW) pbyBuffer)->byChannel = get_channel_number(pMgmt->pAdapter, pMgmt->byNewChannel);
3258 ((PWLAN_IE_CH_SW) pbyBuffer)->byCount = 0;
3259 pbyBuffer += (3) + WLAN_IEHDR_LEN;
3260 uLength += (3) + WLAN_IEHDR_LEN;
3262 // TPC report
3263 ((PWLAN_IE_TPC_REP) pbyBuffer)->byElementID = WLAN_EID_TPC_REP;
3264 ((PWLAN_IE_TPC_REP) pbyBuffer)->len = 2;
3265 ((PWLAN_IE_TPC_REP) pbyBuffer)->byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
3266 ((PWLAN_IE_TPC_REP) pbyBuffer)->byLinkMargin = 0;
3267 pbyBuffer += (2) + WLAN_IEHDR_LEN;
3268 uLength += (2) + WLAN_IEHDR_LEN;
3269 // IBSS DFS
3270 if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP) {
3271 pIBSSDFS = (PWLAN_IE_IBSS_DFS) pbyBuffer;
3272 pIBSSDFS->byElementID = WLAN_EID_IBSS_DFS;
3273 pIBSSDFS->len = 7;
3274 memcpy(pIBSSDFS->abyDFSOwner,
3275 pMgmt->abyIBSSDFSOwner,
3277 pIBSSDFS->byDFSRecovery = pMgmt->byIBSSDFSRecovery;
3278 pbyBuffer += (7) + WLAN_IEHDR_LEN;
3279 uLength += (7) + WLAN_IEHDR_LEN;
3280 for (ii = CB_MAX_CHANNEL_24G + 1; ii <= CB_MAX_CHANNEL; ii++) {
3281 if (get_channel_map_info(pMgmt->pAdapter, ii, pbyBuffer, pbyBuffer+1)) {
3282 pbyBuffer += 2;
3283 uLength += 2;
3284 pIBSSDFS->len += 2;
3288 sFrame.len += uLength;
3291 if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3292 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3293 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3294 memcpy(sFrame.pExtSuppRates,
3295 pCurrExtSuppRates,
3296 ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3300 // hostapd wpa/wpa2 IE
3301 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) && pDevice->bEnableHostapd) {
3302 if (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) {
3303 if (pMgmt->wWPAIELen != 0) {
3304 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3305 memcpy(sFrame.pRSN, pMgmt->abyWPAIE, pMgmt->wWPAIELen);
3306 sFrame.len += pMgmt->wWPAIELen;
3311 // Adjust the length fields
3312 pTxPacket->cbMPDULen = sFrame.len;
3313 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3315 return pTxPacket;
3320 * Routine Description:
3321 * Constructs an association request frame
3324 * Return Value:
3325 * A ptr to frame or NULL on allocation failure
3329 PSTxMgmtPacket
3330 s_MgrMakeAssocRequest(
3331 PSDevice pDevice,
3332 PSMgmtObject pMgmt,
3333 unsigned char *pDAddr,
3334 unsigned short wCurrCapInfo,
3335 unsigned short wListenInterval,
3336 PWLAN_IE_SSID pCurrSSID,
3337 PWLAN_IE_SUPP_RATES pCurrRates,
3338 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3341 PSTxMgmtPacket pTxPacket = NULL;
3342 WLAN_FR_ASSOCREQ sFrame;
3343 unsigned char *pbyIEs;
3344 unsigned char *pbyRSN;
3346 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3347 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3348 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3349 // Setup the sFrame structure.
3350 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3351 sFrame.len = WLAN_ASSOCREQ_FR_MAXLEN;
3352 // format fixed field frame structure
3353 vMgrEncodeAssocRequest(&sFrame);
3354 // Setup the header
3355 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3357 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3358 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCREQ)
3360 memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3361 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3362 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3364 // Set the capability and listen interval
3365 *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3366 *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3368 // sFrame.len point to end of fixed field
3369 sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3370 sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3371 memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3373 pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3374 pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3375 pbyIEs = pMgmt->sAssocInfo.abyIEs;
3376 memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3377 pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3379 // Copy the rate set
3380 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3381 if ((pDevice->eCurrentPHYType == PHY_TYPE_11B) && (pCurrRates->len > 4))
3382 sFrame.len += 4 + WLAN_IEHDR_LEN;
3383 else
3384 sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3385 memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3387 // Copy the extension rate set
3388 if ((pDevice->eCurrentPHYType == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3389 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3390 sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3391 memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3394 pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3395 memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3396 pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3398 // for 802.11h
3399 if (pMgmt->b11hEnable) {
3400 if (sFrame.pCurrPowerCap == NULL) {
3401 sFrame.pCurrPowerCap = (PWLAN_IE_PW_CAP)(sFrame.pBuf + sFrame.len);
3402 sFrame.len += (2 + WLAN_IEHDR_LEN);
3403 sFrame.pCurrPowerCap->byElementID = WLAN_EID_PWR_CAPABILITY;
3404 sFrame.pCurrPowerCap->len = 2;
3405 CARDvGetPowerCapability(pMgmt->pAdapter,
3406 &(sFrame.pCurrPowerCap->byMinPower),
3407 &(sFrame.pCurrPowerCap->byMaxPower)
3410 if (sFrame.pCurrSuppCh == NULL) {
3411 sFrame.pCurrSuppCh = (PWLAN_IE_SUPP_CH)(sFrame.pBuf + sFrame.len);
3412 sFrame.len += set_support_channels(pMgmt->pAdapter, (unsigned char *)sFrame.pCurrSuppCh);
3416 if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3417 (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3418 (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3419 (pMgmt->pCurrBSS != NULL)) {
3420 /* WPA IE */
3421 sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3422 sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3423 sFrame.pRSNWPA->len = 16;
3424 sFrame.pRSNWPA->abyOUI[0] = 0x00;
3425 sFrame.pRSNWPA->abyOUI[1] = 0x50;
3426 sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3427 sFrame.pRSNWPA->abyOUI[3] = 0x01;
3428 sFrame.pRSNWPA->wVersion = 1;
3429 //Group Key Cipher Suite
3430 sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3431 sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3432 sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3433 if (pMgmt->byCSSGK == KEY_CTL_WEP)
3434 sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3435 else if (pMgmt->byCSSGK == KEY_CTL_TKIP)
3436 sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3437 else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
3438 sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3439 else
3440 sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3442 // Pairwise Key Cipher Suite
3443 sFrame.pRSNWPA->wPKCount = 1;
3444 sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3445 sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3446 sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3447 if (pMgmt->byCSSPK == KEY_CTL_TKIP)
3448 sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3449 else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
3450 sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3451 else
3452 sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3454 // Auth Key Management Suite
3455 pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3456 *pbyRSN++ = 0x01;
3457 *pbyRSN++ = 0x00;
3458 *pbyRSN++ = 0x00;
3460 *pbyRSN++ = 0x50;
3461 *pbyRSN++ = 0xf2;
3462 if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)
3463 *pbyRSN++ = WPA_AUTH_PSK;
3464 else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA)
3465 *pbyRSN++ = WPA_AUTH_IEEE802_1X;
3466 else
3467 *pbyRSN++ = WPA_NONE;
3469 sFrame.pRSNWPA->len += 6;
3471 // RSN Capabilities
3473 *pbyRSN++ = 0x00;
3474 *pbyRSN++ = 0x00;
3475 sFrame.pRSNWPA->len += 2;
3477 sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3478 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3479 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3480 memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3481 pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3483 } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3484 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3485 (pMgmt->pCurrBSS != NULL)) {
3486 unsigned int ii;
3487 unsigned short *pwPMKID;
3489 // WPA IE
3490 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3491 sFrame.pRSN->byElementID = WLAN_EID_RSN;
3492 sFrame.pRSN->len = 6; //Version(2)+GK(4)
3493 sFrame.pRSN->wVersion = 1;
3494 //Group Key Cipher Suite
3495 sFrame.pRSN->abyRSN[0] = 0x00;
3496 sFrame.pRSN->abyRSN[1] = 0x0F;
3497 sFrame.pRSN->abyRSN[2] = 0xAC;
3498 if (pMgmt->byCSSGK == KEY_CTL_WEP)
3499 sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3500 else if (pMgmt->byCSSGK == KEY_CTL_TKIP)
3501 sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3502 else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
3503 sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3504 else
3505 sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3507 // Pairwise Key Cipher Suite
3508 sFrame.pRSN->abyRSN[4] = 1;
3509 sFrame.pRSN->abyRSN[5] = 0;
3510 sFrame.pRSN->abyRSN[6] = 0x00;
3511 sFrame.pRSN->abyRSN[7] = 0x0F;
3512 sFrame.pRSN->abyRSN[8] = 0xAC;
3513 if (pMgmt->byCSSPK == KEY_CTL_TKIP)
3514 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3515 else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
3516 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3517 else if (pMgmt->byCSSPK == KEY_CTL_NONE)
3518 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3519 else
3520 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3522 sFrame.pRSN->len += 6;
3524 // Auth Key Management Suite
3525 sFrame.pRSN->abyRSN[10] = 1;
3526 sFrame.pRSN->abyRSN[11] = 0;
3527 sFrame.pRSN->abyRSN[12] = 0x00;
3528 sFrame.pRSN->abyRSN[13] = 0x0F;
3529 sFrame.pRSN->abyRSN[14] = 0xAC;
3530 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)
3531 sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3532 else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)
3533 sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3534 else
3535 sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3537 sFrame.pRSN->len += 6;
3539 // RSN Capabilities
3540 if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) {
3541 memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3542 } else {
3543 sFrame.pRSN->abyRSN[16] = 0;
3544 sFrame.pRSN->abyRSN[17] = 0;
3546 sFrame.pRSN->len += 2;
3548 if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3549 // RSN PMKID
3550 pbyRSN = &sFrame.pRSN->abyRSN[18];
3551 pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
3552 *pwPMKID = 0; // Initialize PMKID count
3553 pbyRSN += 2; // Point to PMKID list
3554 for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3555 if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) {
3556 (*pwPMKID)++;
3557 memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
3558 pbyRSN += 16;
3561 if (*pwPMKID != 0)
3562 sFrame.pRSN->len += (2 + (*pwPMKID)*16);
3565 sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3566 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3567 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3568 memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
3569 pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3572 // Adjust the length fields
3573 pTxPacket->cbMPDULen = sFrame.len;
3574 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3575 return pTxPacket;
3580 * Routine Description:
3581 * Constructs an re-association request frame
3584 * Return Value:
3585 * A ptr to frame or NULL on allocation failure
3589 PSTxMgmtPacket
3590 s_MgrMakeReAssocRequest(
3591 PSDevice pDevice,
3592 PSMgmtObject pMgmt,
3593 unsigned char *pDAddr,
3594 unsigned short wCurrCapInfo,
3595 unsigned short wListenInterval,
3596 PWLAN_IE_SSID pCurrSSID,
3597 PWLAN_IE_SUPP_RATES pCurrRates,
3598 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3601 PSTxMgmtPacket pTxPacket = NULL;
3602 WLAN_FR_REASSOCREQ sFrame;
3603 unsigned char *pbyIEs;
3604 unsigned char *pbyRSN;
3606 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3607 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_REASSOCREQ_FR_MAXLEN);
3608 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3609 /* Setup the sFrame structure. */
3610 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3611 sFrame.len = WLAN_REASSOCREQ_FR_MAXLEN;
3613 // format fixed field frame structure
3614 vMgrEncodeReassocRequest(&sFrame);
3616 /* Setup the header */
3617 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3619 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3620 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCREQ)
3622 memcpy(sFrame.pHdr->sA3.abyAddr1, pDAddr, WLAN_ADDR_LEN);
3623 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3624 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3626 /* Set the capability and listen interval */
3627 *(sFrame.pwCapInfo) = cpu_to_le16(wCurrCapInfo);
3628 *(sFrame.pwListenInterval) = cpu_to_le16(wListenInterval);
3630 memcpy(sFrame.pAddrCurrAP, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3631 /* Copy the SSID */
3632 /* sFrame.len point to end of fixed field */
3633 sFrame.pSSID = (PWLAN_IE_SSID)(sFrame.pBuf + sFrame.len);
3634 sFrame.len += pCurrSSID->len + WLAN_IEHDR_LEN;
3635 memcpy(sFrame.pSSID, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3637 pMgmt->sAssocInfo.AssocInfo.RequestIELength = pCurrSSID->len + WLAN_IEHDR_LEN;
3638 pMgmt->sAssocInfo.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
3639 pbyIEs = pMgmt->sAssocInfo.abyIEs;
3640 memcpy(pbyIEs, pCurrSSID, pCurrSSID->len + WLAN_IEHDR_LEN);
3641 pbyIEs += pCurrSSID->len + WLAN_IEHDR_LEN;
3643 /* Copy the rate set */
3644 /* sFrame.len point to end of SSID */
3645 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3646 sFrame.len += pCurrRates->len + WLAN_IEHDR_LEN;
3647 memcpy(sFrame.pSuppRates, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3649 // Copy the extension rate set
3650 if ((pMgmt->eCurrentPHYMode == PHY_TYPE_11G) && (pCurrExtSuppRates->len > 0)) {
3651 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3652 sFrame.len += pCurrExtSuppRates->len + WLAN_IEHDR_LEN;
3653 memcpy(sFrame.pExtSuppRates, pCurrExtSuppRates, pCurrExtSuppRates->len + WLAN_IEHDR_LEN);
3656 pMgmt->sAssocInfo.AssocInfo.RequestIELength += pCurrRates->len + WLAN_IEHDR_LEN;
3657 memcpy(pbyIEs, pCurrRates, pCurrRates->len + WLAN_IEHDR_LEN);
3658 pbyIEs += pCurrRates->len + WLAN_IEHDR_LEN;
3660 if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA) ||
3661 (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) ||
3662 (pMgmt->eAuthenMode == WMAC_AUTH_WPANONE)) &&
3663 (pMgmt->pCurrBSS != NULL)) {
3664 /* WPA IE */
3665 sFrame.pRSNWPA = (PWLAN_IE_RSN_EXT)(sFrame.pBuf + sFrame.len);
3666 sFrame.pRSNWPA->byElementID = WLAN_EID_RSN_WPA;
3667 sFrame.pRSNWPA->len = 16;
3668 sFrame.pRSNWPA->abyOUI[0] = 0x00;
3669 sFrame.pRSNWPA->abyOUI[1] = 0x50;
3670 sFrame.pRSNWPA->abyOUI[2] = 0xf2;
3671 sFrame.pRSNWPA->abyOUI[3] = 0x01;
3672 sFrame.pRSNWPA->wVersion = 1;
3673 //Group Key Cipher Suite
3674 sFrame.pRSNWPA->abyMulticast[0] = 0x00;
3675 sFrame.pRSNWPA->abyMulticast[1] = 0x50;
3676 sFrame.pRSNWPA->abyMulticast[2] = 0xf2;
3677 if (pMgmt->byCSSGK == KEY_CTL_WEP)
3678 sFrame.pRSNWPA->abyMulticast[3] = pMgmt->pCurrBSS->byGKType;
3679 else if (pMgmt->byCSSGK == KEY_CTL_TKIP)
3680 sFrame.pRSNWPA->abyMulticast[3] = WPA_TKIP;
3681 else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
3682 sFrame.pRSNWPA->abyMulticast[3] = WPA_AESCCMP;
3683 else
3684 sFrame.pRSNWPA->abyMulticast[3] = WPA_NONE;
3686 // Pairwise Key Cipher Suite
3687 sFrame.pRSNWPA->wPKCount = 1;
3688 sFrame.pRSNWPA->PKSList[0].abyOUI[0] = 0x00;
3689 sFrame.pRSNWPA->PKSList[0].abyOUI[1] = 0x50;
3690 sFrame.pRSNWPA->PKSList[0].abyOUI[2] = 0xf2;
3691 if (pMgmt->byCSSPK == KEY_CTL_TKIP)
3692 sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_TKIP;
3693 else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
3694 sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_AESCCMP;
3695 else
3696 sFrame.pRSNWPA->PKSList[0].abyOUI[3] = WPA_NONE;
3698 // Auth Key Management Suite
3699 pbyRSN = (unsigned char *)(sFrame.pBuf + sFrame.len + 2 + sFrame.pRSNWPA->len);
3700 *pbyRSN++ = 0x01;
3701 *pbyRSN++ = 0x00;
3702 *pbyRSN++ = 0x00;
3704 *pbyRSN++ = 0x50;
3705 *pbyRSN++ = 0xf2;
3706 if (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK)
3707 *pbyRSN++ = WPA_AUTH_PSK;
3708 else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA)
3709 *pbyRSN++ = WPA_AUTH_IEEE802_1X;
3710 else
3711 *pbyRSN++ = WPA_NONE;
3713 sFrame.pRSNWPA->len += 6;
3715 // RSN Capabilities
3716 *pbyRSN++ = 0x00;
3717 *pbyRSN++ = 0x00;
3718 sFrame.pRSNWPA->len += 2;
3720 sFrame.len += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3721 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3722 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3723 memcpy(pbyIEs, sFrame.pRSNWPA, sFrame.pRSNWPA->len + WLAN_IEHDR_LEN);
3724 pbyIEs += sFrame.pRSNWPA->len + WLAN_IEHDR_LEN;
3726 } else if (((pMgmt->eAuthenMode == WMAC_AUTH_WPA2) ||
3727 (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)) &&
3728 (pMgmt->pCurrBSS != NULL)) {
3729 unsigned int ii;
3730 unsigned short *pwPMKID;
3732 /* WPA IE */
3733 sFrame.pRSN = (PWLAN_IE_RSN)(sFrame.pBuf + sFrame.len);
3734 sFrame.pRSN->byElementID = WLAN_EID_RSN;
3735 sFrame.pRSN->len = 6; //Version(2)+GK(4)
3736 sFrame.pRSN->wVersion = 1;
3737 //Group Key Cipher Suite
3738 sFrame.pRSN->abyRSN[0] = 0x00;
3739 sFrame.pRSN->abyRSN[1] = 0x0F;
3740 sFrame.pRSN->abyRSN[2] = 0xAC;
3741 if (pMgmt->byCSSGK == KEY_CTL_WEP)
3742 sFrame.pRSN->abyRSN[3] = pMgmt->pCurrBSS->byCSSGK;
3743 else if (pMgmt->byCSSGK == KEY_CTL_TKIP)
3744 sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_TKIP;
3745 else if (pMgmt->byCSSGK == KEY_CTL_CCMP)
3746 sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_CCMP;
3747 else
3748 sFrame.pRSN->abyRSN[3] = WLAN_11i_CSS_UNKNOWN;
3750 // Pairwise Key Cipher Suite
3751 sFrame.pRSN->abyRSN[4] = 1;
3752 sFrame.pRSN->abyRSN[5] = 0;
3753 sFrame.pRSN->abyRSN[6] = 0x00;
3754 sFrame.pRSN->abyRSN[7] = 0x0F;
3755 sFrame.pRSN->abyRSN[8] = 0xAC;
3756 if (pMgmt->byCSSPK == KEY_CTL_TKIP)
3757 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_TKIP;
3758 else if (pMgmt->byCSSPK == KEY_CTL_CCMP)
3759 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_CCMP;
3760 else if (pMgmt->byCSSPK == KEY_CTL_NONE)
3761 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_USE_GROUP;
3762 else
3763 sFrame.pRSN->abyRSN[9] = WLAN_11i_CSS_UNKNOWN;
3765 sFrame.pRSN->len += 6;
3767 // Auth Key Management Suite
3768 sFrame.pRSN->abyRSN[10] = 1;
3769 sFrame.pRSN->abyRSN[11] = 0;
3770 sFrame.pRSN->abyRSN[12] = 0x00;
3771 sFrame.pRSN->abyRSN[13] = 0x0F;
3772 sFrame.pRSN->abyRSN[14] = 0xAC;
3773 if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2PSK)
3774 sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_PSK;
3775 else if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)
3776 sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_802_1X;
3777 else
3778 sFrame.pRSN->abyRSN[15] = WLAN_11i_AKMSS_UNKNOWN;
3780 sFrame.pRSN->len += 6;
3782 // RSN Capabilities
3783 if (pMgmt->pCurrBSS->sRSNCapObj.bRSNCapExist) {
3784 memcpy(&sFrame.pRSN->abyRSN[16], &pMgmt->pCurrBSS->sRSNCapObj.wRSNCap, 2);
3785 } else {
3786 sFrame.pRSN->abyRSN[16] = 0;
3787 sFrame.pRSN->abyRSN[17] = 0;
3789 sFrame.pRSN->len += 2;
3791 if ((pDevice->gsPMKID.BSSIDInfoCount > 0) && pDevice->bRoaming && (pMgmt->eAuthenMode == WMAC_AUTH_WPA2)) {
3792 // RSN PMKID
3793 pbyRSN = &sFrame.pRSN->abyRSN[18];
3794 pwPMKID = (unsigned short *)pbyRSN; // Point to PMKID count
3795 *pwPMKID = 0; // Initialize PMKID count
3796 pbyRSN += 2; // Point to PMKID list
3797 for (ii = 0; ii < pDevice->gsPMKID.BSSIDInfoCount; ii++) {
3798 if (!memcmp(&pDevice->gsPMKID.BSSIDInfo[ii].BSSID[0], pMgmt->abyCurrBSSID, ETH_ALEN)) {
3799 (*pwPMKID)++;
3800 memcpy(pbyRSN, pDevice->gsPMKID.BSSIDInfo[ii].PMKID, 16);
3801 pbyRSN += 16;
3805 if (*pwPMKID != 0)
3806 sFrame.pRSN->len += (2 + (*pwPMKID) * 16);
3809 sFrame.len += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3810 // copy to AssocInfo. for OID_802_11_ASSOCIATION_INFORMATION
3811 pMgmt->sAssocInfo.AssocInfo.RequestIELength += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3812 memcpy(pbyIEs, sFrame.pRSN, sFrame.pRSN->len + WLAN_IEHDR_LEN);
3813 pbyIEs += sFrame.pRSN->len + WLAN_IEHDR_LEN;
3816 /* Adjust the length fields */
3817 pTxPacket->cbMPDULen = sFrame.len;
3818 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3820 return pTxPacket;
3825 * Routine Description:
3826 * Constructs an assoc-response frame
3829 * Return Value:
3830 * PTR to frame; or NULL on allocation failure
3834 PSTxMgmtPacket
3835 s_MgrMakeAssocResponse(
3836 PSDevice pDevice,
3837 PSMgmtObject pMgmt,
3838 unsigned short wCurrCapInfo,
3839 unsigned short wAssocStatus,
3840 unsigned short wAssocAID,
3841 unsigned char *pDstAddr,
3842 PWLAN_IE_SUPP_RATES pCurrSuppRates,
3843 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3846 PSTxMgmtPacket pTxPacket = NULL;
3847 WLAN_FR_ASSOCRESP sFrame;
3849 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3850 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3851 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3852 // Setup the sFrame structure
3853 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3854 sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
3855 vMgrEncodeAssocResponse(&sFrame);
3856 // Setup the header
3857 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3859 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3860 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ASSOCRESP)
3862 memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3863 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3864 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3866 *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3867 *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
3868 *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
3870 // Copy the rate set
3871 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3872 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3873 memcpy(sFrame.pSuppRates,
3874 pCurrSuppRates,
3875 ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3878 if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3879 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3880 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3881 memcpy(sFrame.pExtSuppRates,
3882 pCurrExtSuppRates,
3883 ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3887 // Adjust the length fields
3888 pTxPacket->cbMPDULen = sFrame.len;
3889 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3891 return pTxPacket;
3896 * Routine Description:
3897 * Constructs an reassoc-response frame
3900 * Return Value:
3901 * PTR to frame; or NULL on allocation failure
3905 PSTxMgmtPacket
3906 s_MgrMakeReAssocResponse(
3907 PSDevice pDevice,
3908 PSMgmtObject pMgmt,
3909 unsigned short wCurrCapInfo,
3910 unsigned short wAssocStatus,
3911 unsigned short wAssocAID,
3912 unsigned char *pDstAddr,
3913 PWLAN_IE_SUPP_RATES pCurrSuppRates,
3914 PWLAN_IE_SUPP_RATES pCurrExtSuppRates
3917 PSTxMgmtPacket pTxPacket = NULL;
3918 WLAN_FR_REASSOCRESP sFrame;
3920 pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
3921 memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_ASSOCREQ_FR_MAXLEN);
3922 pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));
3923 // Setup the sFrame structure
3924 sFrame.pBuf = (unsigned char *)pTxPacket->p80211Header;
3925 sFrame.len = WLAN_REASSOCRESP_FR_MAXLEN;
3926 vMgrEncodeReassocResponse(&sFrame);
3927 // Setup the header
3928 sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
3930 WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
3931 WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_REASSOCRESP)
3933 memcpy(sFrame.pHdr->sA3.abyAddr1, pDstAddr, WLAN_ADDR_LEN);
3934 memcpy(sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
3935 memcpy(sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
3937 *sFrame.pwCapInfo = cpu_to_le16(wCurrCapInfo);
3938 *sFrame.pwStatus = cpu_to_le16(wAssocStatus);
3939 *sFrame.pwAid = cpu_to_le16((unsigned short)(wAssocAID | BIT14 | BIT15));
3941 // Copy the rate set
3942 sFrame.pSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3943 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN;
3944 memcpy(sFrame.pSuppRates,
3945 pCurrSuppRates,
3946 ((PWLAN_IE_SUPP_RATES)pCurrSuppRates)->len + WLAN_IEHDR_LEN
3949 if (((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len != 0) {
3950 sFrame.pExtSuppRates = (PWLAN_IE_SUPP_RATES)(sFrame.pBuf + sFrame.len);
3951 sFrame.len += ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN;
3952 memcpy(sFrame.pExtSuppRates,
3953 pCurrExtSuppRates,
3954 ((PWLAN_IE_SUPP_RATES)pCurrExtSuppRates)->len + WLAN_IEHDR_LEN
3958 // Adjust the length fields
3959 pTxPacket->cbMPDULen = sFrame.len;
3960 pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
3962 return pTxPacket;
3967 * Routine Description:
3968 * Handles probe response management frames.
3971 * Return Value:
3972 * none.
3976 static
3977 void
3978 s_vMgrRxProbeResponse(
3979 PSDevice pDevice,
3980 PSMgmtObject pMgmt,
3981 PSRxMgmtPacket pRxPacket
3984 PKnownBSS pBSSList = NULL;
3985 WLAN_FR_PROBERESP sFrame;
3986 unsigned char byCurrChannel = pRxPacket->byRxChannel;
3987 ERPObject sERP;
3988 unsigned char byIEChannel = 0;
3989 bool bChannelHit = true;
3991 memset(&sFrame, 0, sizeof(WLAN_FR_PROBERESP));
3992 // decode the frame
3993 sFrame.len = pRxPacket->cbMPDULen;
3994 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
3995 vMgrDecodeProbeResponse(&sFrame);
3997 if ((sFrame.pqwTimestamp == NULL) ||
3998 (sFrame.pwBeaconInterval == NULL) ||
3999 (sFrame.pwCapInfo == NULL) ||
4000 (sFrame.pSSID == NULL) ||
4001 (sFrame.pSuppRates == NULL)) {
4002 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
4003 DBG_PORT80(0xCC);
4004 return;
4007 if (sFrame.pSSID->len == 0)
4008 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
4010 if (sFrame.pDSParms != NULL) {
4011 if (byCurrChannel > CB_MAX_CHANNEL_24G) {
4012 // channel remapping to
4013 byIEChannel = get_channel_mapping(pMgmt->pAdapter, sFrame.pDSParms->byCurrChannel, PHY_TYPE_11A);
4014 } else {
4015 byIEChannel = sFrame.pDSParms->byCurrChannel;
4017 if (byCurrChannel != byIEChannel) {
4018 // adjust channel info. bcs we rcv adjacent channel packets
4019 bChannelHit = false;
4020 byCurrChannel = byIEChannel;
4022 } else {
4023 // no DS channel info
4024 bChannelHit = true;
4027 //2008-0730-01<Add>by MikeLiu
4028 if (ChannelExceedZoneType(pDevice, byCurrChannel))
4029 return;
4031 if (sFrame.pERP != NULL) {
4032 sERP.byERP = sFrame.pERP->byContext;
4033 sERP.bERPExist = true;
4034 } else {
4035 sERP.bERPExist = false;
4036 sERP.byERP = 0;
4039 // update or insert the bss
4040 pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID);
4041 if (pBSSList) {
4042 BSSbUpdateToBSSList((void *)pDevice,
4043 *sFrame.pqwTimestamp,
4044 *sFrame.pwBeaconInterval,
4045 *sFrame.pwCapInfo,
4046 byCurrChannel,
4047 bChannelHit,
4048 sFrame.pSSID,
4049 sFrame.pSuppRates,
4050 sFrame.pExtSuppRates,
4051 &sERP,
4052 sFrame.pRSN,
4053 sFrame.pRSNWPA,
4054 sFrame.pIE_Country,
4055 sFrame.pIE_Quiet,
4056 pBSSList,
4057 sFrame.len - WLAN_HDR_ADDR3_LEN,
4058 sFrame.pHdr->sA4.abyAddr4, // payload of probresponse
4059 (void *)pRxPacket
4061 } else {
4062 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp/insert: RxChannel = : %d\n", byCurrChannel);
4063 BSSbInsertToBSSList((void *)pDevice,
4064 sFrame.pHdr->sA3.abyAddr3,
4065 *sFrame.pqwTimestamp,
4066 *sFrame.pwBeaconInterval,
4067 *sFrame.pwCapInfo,
4068 byCurrChannel,
4069 sFrame.pSSID,
4070 sFrame.pSuppRates,
4071 sFrame.pExtSuppRates,
4072 &sERP,
4073 sFrame.pRSN,
4074 sFrame.pRSNWPA,
4075 sFrame.pIE_Country,
4076 sFrame.pIE_Quiet,
4077 sFrame.len - WLAN_HDR_ADDR3_LEN,
4078 sFrame.pHdr->sA4.abyAddr4, // payload of beacon
4079 (void *)pRxPacket
4082 return;
4087 * Routine Description:(AP)or(Ad-hoc STA)
4088 * Handles probe request management frames.
4091 * Return Value:
4092 * none.
4096 static
4097 void
4098 s_vMgrRxProbeRequest(
4099 PSDevice pDevice,
4100 PSMgmtObject pMgmt,
4101 PSRxMgmtPacket pRxPacket
4104 WLAN_FR_PROBEREQ sFrame;
4105 CMD_STATUS Status;
4106 PSTxMgmtPacket pTxPacket;
4107 unsigned char byPHYType = BB_TYPE_11B;
4109 // STA in Ad-hoc mode: when latest TBTT beacon transmit success,
4110 // STA have to response this request.
4111 if ((pMgmt->eCurrMode == WMAC_MODE_ESS_AP) ||
4112 ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) && pDevice->bBeaconSent)) {
4113 memset(&sFrame, 0, sizeof(WLAN_FR_PROBEREQ));
4114 // decode the frame
4115 sFrame.len = pRxPacket->cbMPDULen;
4116 sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header;
4117 vMgrDecodeProbeRequest(&sFrame);
4119 if (sFrame.pSSID->len != 0) {
4120 if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len)
4121 return;
4122 if (memcmp(sFrame.pSSID->abySSID,
4123 ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->abySSID,
4124 ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) != 0) {
4125 return;
4129 if ((sFrame.pSuppRates->len > 4) || (sFrame.pExtSuppRates != NULL))
4130 byPHYType = BB_TYPE_11G;
4132 // Probe response reply..
4133 pTxPacket = s_MgrMakeProbeResponse
4135 pDevice,
4136 pMgmt,
4137 pMgmt->wCurrCapInfo,
4138 pMgmt->wCurrBeaconPeriod,
4139 pMgmt->uCurrChannel,
4141 sFrame.pHdr->sA3.abyAddr2,
4142 (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4143 (unsigned char *)pMgmt->abyCurrBSSID,
4144 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4145 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates,
4146 byPHYType
4148 if (pTxPacket != NULL) {
4149 /* send the frame */
4150 Status = csMgmt_xmit(pDevice, pTxPacket);
4151 if (Status != CMD_STATUS_PENDING) {
4152 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n");
4157 return;
4162 * Routine Description:
4164 * Entry point for the reception and handling of 802.11 management
4165 * frames. Makes a determination of the frame type and then calls
4166 * the appropriate function.
4169 * Return Value:
4170 * none.
4174 void
4175 vMgrRxManagePacket(
4176 void *hDeviceContext,
4177 PSMgmtObject pMgmt,
4178 PSRxMgmtPacket pRxPacket
4181 PSDevice pDevice = (PSDevice)hDeviceContext;
4182 bool bInScan = false;
4183 unsigned int uNodeIndex = 0;
4184 NODE_STATE eNodeState = 0;
4185 CMD_STATUS Status;
4187 if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) {
4188 if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex))
4189 eNodeState = pMgmt->sNodeDBTable[uNodeIndex].eNodeState;
4192 switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) {
4193 case WLAN_FSTYPE_ASSOCREQ:
4194 // Frame Clase = 2
4195 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n");
4196 if (eNodeState < NODE_AUTH) {
4197 // send deauth notification
4198 // reason = (6) class 2 received from nonauth sta
4199 vMgrDeAuthenBeginSta(pDevice,
4200 pMgmt,
4201 pRxPacket->p80211Header->sA3.abyAddr2,
4202 (6),
4203 &Status
4205 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n");
4206 } else {
4207 s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4209 break;
4211 case WLAN_FSTYPE_ASSOCRESP:
4212 // Frame Clase = 2
4213 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n");
4214 s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false);
4215 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n");
4216 break;
4218 case WLAN_FSTYPE_REASSOCREQ:
4219 // Frame Clase = 2
4220 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n");
4221 // Todo: reassoc
4222 if (eNodeState < NODE_AUTH) {
4223 // send deauth notification
4224 // reason = (6) class 2 received from nonauth sta
4225 vMgrDeAuthenBeginSta(pDevice,
4226 pMgmt,
4227 pRxPacket->p80211Header->sA3.abyAddr2,
4228 (6),
4229 &Status
4231 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n");
4234 s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex);
4235 break;
4237 case WLAN_FSTYPE_REASSOCRESP:
4238 // Frame Clase = 2
4239 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n");
4240 s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true);
4241 break;
4243 case WLAN_FSTYPE_PROBEREQ:
4244 // Frame Clase = 0
4245 s_vMgrRxProbeRequest(pDevice, pMgmt, pRxPacket);
4246 break;
4248 case WLAN_FSTYPE_PROBERESP:
4249 // Frame Clase = 0
4250 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n");
4252 s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket);
4253 break;
4255 case WLAN_FSTYPE_BEACON:
4256 // Frame Clase = 0
4257 if (pMgmt->eScanState != WMAC_NO_SCANNING)
4258 bInScan = true;
4260 s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
4261 break;
4263 case WLAN_FSTYPE_ATIM:
4264 // Frame Clase = 1
4265 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n");
4266 break;
4268 case WLAN_FSTYPE_DISASSOC:
4269 // Frame Clase = 2
4270 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n");
4271 if (eNodeState < NODE_AUTH) {
4272 // send deauth notification
4273 // reason = (6) class 2 received from nonauth sta
4274 vMgrDeAuthenBeginSta(pDevice,
4275 pMgmt,
4276 pRxPacket->p80211Header->sA3.abyAddr2,
4277 (6),
4278 &Status
4280 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n");
4282 s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket);
4283 break;
4285 case WLAN_FSTYPE_AUTHEN:
4286 // Frame Clase = 1
4287 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx authen\n");
4288 s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket);
4289 break;
4291 case WLAN_FSTYPE_DEAUTHEN:
4292 // Frame Clase = 1
4293 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n");
4294 s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket);
4295 break;
4297 default:
4298 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n");
4301 return;
4306 * Routine Description:
4309 * Prepare beacon to send
4311 * Return Value:
4312 * true if success; false if failed.
4315 bool
4316 bMgrPrepareBeaconToSend(
4317 void *hDeviceContext,
4318 PSMgmtObject pMgmt
4321 PSDevice pDevice = (PSDevice)hDeviceContext;
4322 PSTxMgmtPacket pTxPacket;
4324 if (pDevice->bEncryptionEnable || pDevice->bEnable8021x)
4325 pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
4326 else
4327 pMgmt->wCurrCapInfo &= ~WLAN_SET_CAP_INFO_PRIVACY(1);
4329 pTxPacket = s_MgrMakeBeacon
4331 pDevice,
4332 pMgmt,
4333 pMgmt->wCurrCapInfo,
4334 pMgmt->wCurrBeaconPeriod,
4335 pMgmt->uCurrChannel,
4336 pMgmt->wCurrATIMWindow,
4337 (PWLAN_IE_SSID)pMgmt->abyCurrSSID,
4338 (unsigned char *)pMgmt->abyCurrBSSID,
4339 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
4340 (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
4343 if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) &&
4344 (pMgmt->abyCurrBSSID[0] == 0))
4345 return false;
4347 csBeacon_xmit(pDevice, pTxPacket);
4349 return true;
4354 * Routine Description:
4356 * Log a warning message based on the contents of the Status
4357 * Code field of an 802.11 management frame. Defines are
4358 * derived from 802.11-1997 SPEC.
4360 * Return Value:
4361 * none.
4364 static
4365 void
4366 s_vMgrLogStatus(
4367 PSMgmtObject pMgmt,
4368 unsigned short wStatus
4371 switch (wStatus) {
4372 case WLAN_MGMT_STATUS_UNSPEC_FAILURE:
4373 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n");
4374 break;
4375 case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED:
4376 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n");
4377 break;
4378 case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC:
4379 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n");
4380 break;
4381 case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC:
4382 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n");
4383 break;
4384 case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG:
4385 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n");
4386 break;
4387 case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ:
4388 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n");
4389 break;
4390 case WLAN_MGMT_STATUS_CHALLENGE_FAIL:
4391 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge failure.\n");
4392 break;
4393 case WLAN_MGMT_STATUS_AUTH_TIMEOUT:
4394 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n");
4395 break;
4396 case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY:
4397 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n");
4398 break;
4399 case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES:
4400 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n");
4401 break;
4402 case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE:
4403 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n");
4404 break;
4405 case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC:
4406 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n");
4407 break;
4408 case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY:
4409 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n");
4410 break;
4411 default:
4412 DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus);
4413 break;
4419 * Description:
4420 * Add BSSID in PMKID Candidate list.
4422 * Parameters:
4423 * In:
4424 * hDeviceContext - device structure point
4425 * pbyBSSID - BSSID address for adding
4426 * wRSNCap - BSS's RSN capability
4427 * Out:
4428 * none
4430 * Return Value: none.
4433 bool
4434 bAdd_PMKID_Candidate(
4435 void *hDeviceContext,
4436 unsigned char *pbyBSSID,
4437 PSRSNCapObject psRSNCapObj
4440 PSDevice pDevice = (PSDevice)hDeviceContext;
4441 PPMKID_CANDIDATE pCandidateList;
4442 unsigned int ii = 0;
4444 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4446 if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL))
4447 return false;
4449 if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST)
4450 return false;
4452 // Update Old Candidate
4453 for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) {
4454 pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[ii];
4455 if (!memcmp(pCandidateList->BSSID, pbyBSSID, ETH_ALEN)) {
4456 if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0))
4457 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4458 else
4459 pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4461 return true;
4465 // New Candidate
4466 pCandidateList = &pDevice->gsPMKIDCandidate.CandidateList[pDevice->gsPMKIDCandidate.NumCandidates];
4467 if (psRSNCapObj->bRSNCapExist && (psRSNCapObj->wRSNCap & BIT0))
4468 pCandidateList->Flags |= NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
4469 else
4470 pCandidateList->Flags &= ~(NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED);
4472 memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN);
4473 pDevice->gsPMKIDCandidate.NumCandidates++;
4474 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates);
4475 return true;
4480 * Description:
4481 * Flush PMKID Candidate list.
4483 * Parameters:
4484 * In:
4485 * hDeviceContext - device structure point
4486 * Out:
4487 * none
4489 * Return Value: none.
4492 void
4493 vFlush_PMKID_Candidate(
4494 void *hDeviceContext
4497 PSDevice pDevice = (PSDevice)hDeviceContext;
4499 if (pDevice == NULL)
4500 return;
4502 memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent));
4505 static bool
4506 s_bCipherMatch(
4507 PKnownBSS pBSSNode,
4508 NDIS_802_11_ENCRYPTION_STATUS EncStatus,
4509 unsigned char *pbyCCSPK,
4510 unsigned char *pbyCCSGK
4513 unsigned char byMulticastCipher = KEY_CTL_INVALID;
4514 unsigned char byCipherMask = 0x00;
4515 int i;
4517 if (pBSSNode == NULL)
4518 return false;
4520 // check cap. of BSS
4521 if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4522 (EncStatus == Ndis802_11Encryption1Enabled)) {
4523 // default is WEP only
4524 byMulticastCipher = KEY_CTL_WEP;
4527 if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4528 pBSSNode->bWPA2Valid &&
4529 //20080123-01,<Add> by Einsn Liu
4530 ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
4531 //WPA2
4532 // check Group Key Cipher
4533 if ((pBSSNode->byCSSGK == WLAN_11i_CSS_WEP40) ||
4534 (pBSSNode->byCSSGK == WLAN_11i_CSS_WEP104)) {
4535 byMulticastCipher = KEY_CTL_WEP;
4536 } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_TKIP) {
4537 byMulticastCipher = KEY_CTL_TKIP;
4538 } else if (pBSSNode->byCSSGK == WLAN_11i_CSS_CCMP) {
4539 byMulticastCipher = KEY_CTL_CCMP;
4540 } else {
4541 byMulticastCipher = KEY_CTL_INVALID;
4544 // check Pairwise Key Cipher
4545 for (i = 0; i < pBSSNode->wCSSPKCount; i++) {
4546 if ((pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP40) ||
4547 (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_WEP104)) {
4548 // this should not happen as defined 802.11i
4549 byCipherMask |= 0x01;
4550 } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_TKIP) {
4551 byCipherMask |= 0x02;
4552 } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_CCMP) {
4553 byCipherMask |= 0x04;
4554 } else if (pBSSNode->abyCSSPK[i] == WLAN_11i_CSS_USE_GROUP) {
4555 // use group key only ignore all others
4556 byCipherMask = 0;
4557 i = pBSSNode->wCSSPKCount;
4561 } else if ((WLAN_GET_CAP_INFO_PRIVACY(pBSSNode->wCapInfo) != 0) &&
4562 pBSSNode->bWPAValid &&
4563 ((EncStatus == Ndis802_11Encryption3Enabled) || (EncStatus == Ndis802_11Encryption2Enabled))) {
4564 //WPA
4565 // check Group Key Cipher
4566 if ((pBSSNode->byGKType == WPA_WEP40) ||
4567 (pBSSNode->byGKType == WPA_WEP104)) {
4568 byMulticastCipher = KEY_CTL_WEP;
4569 } else if (pBSSNode->byGKType == WPA_TKIP) {
4570 byMulticastCipher = KEY_CTL_TKIP;
4571 } else if (pBSSNode->byGKType == WPA_AESCCMP) {
4572 byMulticastCipher = KEY_CTL_CCMP;
4573 } else {
4574 byMulticastCipher = KEY_CTL_INVALID;
4577 // check Pairwise Key Cipher
4578 for (i = 0; i < pBSSNode->wPKCount; i++) {
4579 if (pBSSNode->abyPKType[i] == WPA_TKIP) {
4580 byCipherMask |= 0x02;
4581 } else if (pBSSNode->abyPKType[i] == WPA_AESCCMP) {
4582 byCipherMask |= 0x04;
4583 } else if (pBSSNode->abyPKType[i] == WPA_NONE) {
4584 // use group key only ignore all others
4585 byCipherMask = 0;
4586 i = pBSSNode->wPKCount;
4591 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%d, %d, %d, %d, EncStatus:%d\n",
4592 byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus);
4594 // mask our cap. with BSS
4595 if (EncStatus == Ndis802_11Encryption1Enabled) {
4596 // For supporting Cisco migration mode, don't care pairwise key cipher
4597 if ((byMulticastCipher == KEY_CTL_WEP) &&
4598 (byCipherMask == 0)) {
4599 *pbyCCSGK = KEY_CTL_WEP;
4600 *pbyCCSPK = KEY_CTL_NONE;
4601 return true;
4602 } else {
4603 return false;
4606 } else if (EncStatus == Ndis802_11Encryption2Enabled) {
4607 if ((byMulticastCipher == KEY_CTL_TKIP) &&
4608 (byCipherMask == 0)) {
4609 *pbyCCSGK = KEY_CTL_TKIP;
4610 *pbyCCSPK = KEY_CTL_NONE;
4611 return true;
4612 } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4613 ((byCipherMask & 0x02) != 0)) {
4614 *pbyCCSGK = KEY_CTL_WEP;
4615 *pbyCCSPK = KEY_CTL_TKIP;
4616 return true;
4617 } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4618 ((byCipherMask & 0x02) != 0)) {
4619 *pbyCCSGK = KEY_CTL_TKIP;
4620 *pbyCCSPK = KEY_CTL_TKIP;
4621 return true;
4622 } else {
4623 return false;
4625 } else if (EncStatus == Ndis802_11Encryption3Enabled) {
4626 if ((byMulticastCipher == KEY_CTL_CCMP) &&
4627 (byCipherMask == 0)) {
4628 // When CCMP is enable, "Use group cipher suite" shall not be a valid option.
4629 return false;
4630 } else if ((byMulticastCipher == KEY_CTL_WEP) &&
4631 ((byCipherMask & 0x04) != 0)) {
4632 *pbyCCSGK = KEY_CTL_WEP;
4633 *pbyCCSPK = KEY_CTL_CCMP;
4634 return true;
4635 } else if ((byMulticastCipher == KEY_CTL_TKIP) &&
4636 ((byCipherMask & 0x04) != 0)) {
4637 *pbyCCSGK = KEY_CTL_TKIP;
4638 *pbyCCSPK = KEY_CTL_CCMP;
4639 return true;
4640 } else if ((byMulticastCipher == KEY_CTL_CCMP) &&
4641 ((byCipherMask & 0x04) != 0)) {
4642 *pbyCCSGK = KEY_CTL_CCMP;
4643 *pbyCCSPK = KEY_CTL_CCMP;
4644 return true;
4645 } else {
4646 return false;
4649 return true;