Staging: rt2860: remove dead EXT_BUILD_CHANNEL_LIST code
[linux-2.6] / drivers / staging / rt2860 / sta / connect.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         connect.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         John                    2004-08-08                      Major modification from RT2560
36 */
37 #include "../rt_config.h"
38
39 UCHAR   CipherSuiteWpaNoneTkip[] = {
40                 0x00, 0x50, 0xf2, 0x01, // oui
41                 0x01, 0x00,                             // Version
42                 0x00, 0x50, 0xf2, 0x02, // Multicast
43                 0x01, 0x00,                             // Number of unicast
44                 0x00, 0x50, 0xf2, 0x02, // unicast
45                 0x01, 0x00,                             // number of authentication method
46                 0x00, 0x50, 0xf2, 0x00  // authentication
47                 };
48 UCHAR   CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
49
50 UCHAR   CipherSuiteWpaNoneAes[] = {
51                 0x00, 0x50, 0xf2, 0x01, // oui
52                 0x01, 0x00,                             // Version
53                 0x00, 0x50, 0xf2, 0x04, // Multicast
54                 0x01, 0x00,                             // Number of unicast
55                 0x00, 0x50, 0xf2, 0x04, // unicast
56                 0x01, 0x00,                             // number of authentication method
57                 0x00, 0x50, 0xf2, 0x00  // authentication
58                 };
59 UCHAR   CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
60
61 // The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
62 // or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
63 // All settings successfuly negotiated furing MLME state machines become final settings
64 // and are copied to pAd->StaActive
65 #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
66 {                                                                                       \
67         (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen;                                \
68         NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
69         COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid);                      \
70         (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel;                                \
71         (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel;                  \
72         (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid;                                        \
73         (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin;                                \
74         (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo;                  \
75         (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod;                      \
76         (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration;                  \
77         (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod;                            \
78         (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen;                          \
79         NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
80         (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen;                          \
81         NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
82         NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
83         NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
84         NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
85         COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid);      \
86         (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid;                       \
87         (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
88         COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
89         (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
90 }
91
92 /*
93         ==========================================================================
94         Description:
95
96         IRQL = PASSIVE_LEVEL
97
98         ==========================================================================
99 */
100 VOID MlmeCntlInit(
101         IN PRTMP_ADAPTER pAd,
102         IN STATE_MACHINE *S,
103         OUT STATE_MACHINE_FUNC Trans[])
104 {
105         // Control state machine differs from other state machines, the interface
106         // follows the standard interface
107         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
108 }
109
110 /*
111         ==========================================================================
112         Description:
113
114         IRQL = DISPATCH_LEVEL
115
116         ==========================================================================
117 */
118 VOID MlmeCntlMachinePerformAction(
119         IN PRTMP_ADAPTER pAd,
120         IN STATE_MACHINE *S,
121         IN MLME_QUEUE_ELEM *Elem)
122 {
123         switch(pAd->Mlme.CntlMachine.CurrState)
124         {
125                 case CNTL_IDLE:
126                         {
127                                 CntlIdleProc(pAd, Elem);
128                         }
129                         break;
130                 case CNTL_WAIT_DISASSOC:
131                         CntlWaitDisassocProc(pAd, Elem);
132                         break;
133                 case CNTL_WAIT_JOIN:
134                         CntlWaitJoinProc(pAd, Elem);
135                         break;
136
137                 // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
138                 // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
139                 // Therefore not protected by NDIS's "only one outstanding OID request"
140                 // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
141                 // Current approach is to block new SET request at RTMPSetInformation()
142                 // when CntlMachine.CurrState is not CNTL_IDLE
143                 case CNTL_WAIT_REASSOC:
144                         CntlWaitReassocProc(pAd, Elem);
145                         break;
146
147                 case CNTL_WAIT_START:
148                         CntlWaitStartProc(pAd, Elem);
149                         break;
150                 case CNTL_WAIT_AUTH:
151                         CntlWaitAuthProc(pAd, Elem);
152                         break;
153                 case CNTL_WAIT_AUTH2:
154                         CntlWaitAuthProc2(pAd, Elem);
155                         break;
156                 case CNTL_WAIT_ASSOC:
157                         CntlWaitAssocProc(pAd, Elem);
158                         break;
159
160                 case CNTL_WAIT_OID_LIST_SCAN:
161                         if(Elem->MsgType == MT2_SCAN_CONF)
162                         {
163                                 // Resume TxRing after SCANING complete. We hope the out-of-service time
164                                 // won't be too long to let upper layer time-out the waiting frames
165                                 RTMPResumeMsduTransmission(pAd);
166                                 if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
167                                 {
168                                         // Cisco scan request is finished, prepare beacon report
169                                         MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
170                                 }
171                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
172
173                 //
174                                 // Set LED status to previous status.
175                                 //
176                                 if (pAd->bLedOnScanning)
177                                 {
178                                         pAd->bLedOnScanning = FALSE;
179                                         RTMPSetLED(pAd, pAd->LedStatus);
180                                 }
181 #ifdef DOT11N_DRAFT3
182                                 // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
183                                 if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
184                                 {
185                                         Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
186                                 }
187 #endif // DOT11N_DRAFT3 //
188                         }
189                         break;
190
191                 case CNTL_WAIT_OID_DISASSOC:
192                         if (Elem->MsgType == MT2_DISASSOC_CONF)
193                         {
194                                 LinkDown(pAd, FALSE);
195                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
196                         }
197                         break;
198                 default:
199                         DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
200                         break;
201         }
202 }
203
204
205 /*
206         ==========================================================================
207         Description:
208
209         IRQL = DISPATCH_LEVEL
210
211         ==========================================================================
212 */
213 VOID CntlIdleProc(
214         IN PRTMP_ADAPTER pAd,
215         IN MLME_QUEUE_ELEM *Elem)
216 {
217         MLME_DISASSOC_REQ_STRUCT   DisassocReq;
218
219         if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
220                 return;
221
222         switch(Elem->MsgType)
223         {
224                 case OID_802_11_SSID:
225                         CntlOidSsidProc(pAd, Elem);
226                         break;
227
228                 case OID_802_11_BSSID:
229                         CntlOidRTBssidProc(pAd,Elem);
230                         break;
231
232                 case OID_802_11_BSSID_LIST_SCAN:
233                         CntlOidScanProc(pAd,Elem);
234                         break;
235
236                 case OID_802_11_DISASSOCIATE:
237                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
238                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
239                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
240 #ifdef WPA_SUPPLICANT_SUPPORT
241             if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
242 #endif // WPA_SUPPLICANT_SUPPORT //
243             {
244                         // Set the AutoReconnectSsid to prevent it reconnect to old SSID
245                         // Since calling this indicate user don't want to connect to that SSID anymore.
246                         pAd->MlmeAux.AutoReconnectSsidLen= 32;
247                         NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
248             }
249                         break;
250
251                 case MT2_MLME_ROAMING_REQ:
252                         CntlMlmeRoamingProc(pAd, Elem);
253                         break;
254
255         case OID_802_11_MIC_FAILURE_REPORT_FRAME:
256             WpaMicFailureReportFrame(pAd, Elem);
257             break;
258
259                 default:
260                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
261                         break;
262         }
263 }
264
265 VOID CntlOidScanProc(
266         IN PRTMP_ADAPTER pAd,
267         IN MLME_QUEUE_ELEM *Elem)
268 {
269         MLME_SCAN_REQ_STRUCT       ScanReq;
270         ULONG                      BssIdx = BSS_NOT_FOUND;
271         BSS_ENTRY                  CurrBss;
272
273         // record current BSS if network is connected.
274         // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
275         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
276         {
277                 BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
278                 if (BssIdx != BSS_NOT_FOUND)
279                 {
280                         NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
281                 }
282         }
283
284         // clean up previous SCAN result, add current BSS back to table if any
285         BssTableInit(&pAd->ScanTab);
286         if (BssIdx != BSS_NOT_FOUND)
287         {
288                 // DDK Note: If the NIC is associated with a particular BSSID and SSID
289                 //    that are not contained in the list of BSSIDs generated by this scan, the
290                 //    BSSID description of the currently associated BSSID and SSID should be
291                 //    appended to the list of BSSIDs in the NIC's database.
292                 // To ensure this, we append this BSS as the first entry in SCAN result
293                 NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
294                 pAd->ScanTab.BssNr = 1;
295         }
296
297         ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
298         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
299                 sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
300         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
301 }
302
303 /*
304         ==========================================================================
305         Description:
306                 Before calling this routine, user desired SSID should already been
307                 recorded in CommonCfg.Ssid[]
308         IRQL = DISPATCH_LEVEL
309
310         ==========================================================================
311 */
312 VOID CntlOidSsidProc(
313         IN PRTMP_ADAPTER pAd,
314         IN MLME_QUEUE_ELEM * Elem)
315 {
316         PNDIS_802_11_SSID          pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
317         MLME_DISASSOC_REQ_STRUCT   DisassocReq;
318         ULONG                                      Now;
319
320         // BBP and RF are not accessible in PS mode, we has to wake them up first
321         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
322                 AsicForceWakeup(pAd, RTMP_HALT);
323
324         // Step 1. record the desired user settings to MlmeAux
325         NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
326         NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
327         pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
328         NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
329         pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
330
331
332         //
333         // Update Reconnect Ssid, that user desired to connect.
334         //
335         NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
336         NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
337         pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
338
339         // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
340         //    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
341         BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
342
343         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
344                         pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
345         NdisGetSystemUpTime(&Now);
346
347         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
348                 (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
349                 NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
350                 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
351         {
352                 // Case 1. already connected with an AP who has the desired SSID
353                 //         with highest RSSI
354
355                 // Add checking Mode "LEAP" for CCX 1.0
356                 if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
357                          (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
358                          (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
359                          (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
360 #ifdef LEAP_SUPPORT
361                          || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
362 #endif // LEAP_SUPPORT //
363                          ) &&
364                         (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
365                 {
366                         // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
367                         //          connection process
368                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
369                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
370                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
371                                                 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
372                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
373                 }
374                 else if (pAd->bConfigChanged == TRUE)
375                 {
376                         // case 1.2 Important Config has changed, we have to reconnect to the same AP
377                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
378                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
379                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
380                                                 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
381                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
382                 }
383                 else
384                 {
385                         // case 1.3. already connected to the SSID with highest RSSI.
386                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
387                         //
388                         // (HCT 12.1) 1c_wlan_mediaevents required
389                         // media connect events are indicated when associating with the same AP
390                         //
391                         if (INFRA_ON(pAd))
392                         {
393                                 //
394                                 // Since MediaState already is NdisMediaStateConnected
395                                 // We just indicate the connect event again to meet the WHQL required.
396                                 //
397                                 pAd->IndicateMediaState = NdisMediaStateConnected;
398                                 RTMP_IndicateMediaState(pAd);
399                 pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
400                         }
401
402                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
403 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
404             {
405                 union iwreq_data    wrqu;
406
407                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
408                 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
409                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
410
411             }
412 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
413                 }
414         }
415         else if (INFRA_ON(pAd))
416         {
417                 //
418                 // For RT61
419                 // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
420                 // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
421                 // But media status is connected, so the SSID not report correctly.
422                 //
423                 if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
424                 {
425                         //
426                         // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
427                         //
428                         pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
429                 }
430                 // case 2. active INFRA association existent
431                 //    roaming is done within miniport driver, nothing to do with configuration
432                 //    utility. so upon a new SET(OID_802_11_SSID) is received, we just
433                 //    disassociate with the current associated AP,
434                 //    then perform a new association with this new SSID, no matter the
435                 //    new/old SSID are the same or not.
436                 DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
437                 DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
438                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
439                                         sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
440                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
441         }
442         else
443         {
444                 if (ADHOC_ON(pAd))
445                 {
446                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
447                         LinkDown(pAd, FALSE);
448                         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
449                         pAd->IndicateMediaState = NdisMediaStateDisconnected;
450                         RTMP_IndicateMediaState(pAd);
451             pAd->ExtraInfo = GENERAL_LINK_DOWN;
452                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
453                 }
454
455                 if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
456                         (pAd->StaCfg.bAutoReconnect == TRUE) &&
457                         (pAd->MlmeAux.BssType == BSS_INFRA) &&
458                         (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
459                         )
460                 {
461                         MLME_SCAN_REQ_STRUCT       ScanReq;
462
463                         DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
464                         ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
465                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
466                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
467                         // Reset Missed scan number
468                         pAd->StaCfg.LastScanTime = Now;
469                 }
470                 else
471                 {
472                         pAd->MlmeAux.BssIdx = 0;
473                         IterateOnBssTab(pAd);
474                 }
475         }
476 }
477
478
479 /*
480         ==========================================================================
481         Description:
482
483         IRQL = DISPATCH_LEVEL
484
485         ==========================================================================
486 */
487 VOID CntlOidRTBssidProc(
488         IN PRTMP_ADAPTER pAd,
489         IN MLME_QUEUE_ELEM * Elem)
490 {
491         ULONG       BssIdx;
492         PUCHAR      pOidBssid = (PUCHAR)Elem->Msg;
493         MLME_DISASSOC_REQ_STRUCT    DisassocReq;
494         MLME_JOIN_REQ_STRUCT        JoinReq;
495
496         // record user desired settings
497         COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
498         pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
499
500         //
501         // Update Reconnect Ssid, that user desired to connect.
502         //
503         NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
504         pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
505         NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
506
507         // find the desired BSS in the latest SCAN result table
508         BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
509         if (BssIdx == BSS_NOT_FOUND)
510         {
511                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
512                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
513                 return;
514         }
515
516         // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
517         // Because we need this entry to become the JOIN target in later on SYNC state machine
518         pAd->MlmeAux.BssIdx = 0;
519         pAd->MlmeAux.SsidBssTab.BssNr = 1;
520         NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
521
522         // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
523         //   we just follow normal procedure. The reason of user doing this may because he/she changed
524         //   AP to another channel, but we still received BEACON from it thus don't claim Link Down.
525         //   Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
526         //   checking, we'll disassociate then re-do normal association with this AP at the new channel.
527         // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
528         //   connection when setting the same BSSID.
529         if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
530                 MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
531         {
532                 // already connected to the same BSSID, go back to idle state directly
533                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
534                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
535 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
536             {
537                 union iwreq_data    wrqu;
538
539                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
540                 memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
541                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
542
543             }
544 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
545         }
546         else
547         {
548                 if (INFRA_ON(pAd))
549                 {
550                         // disassoc from current AP first
551                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
552                         DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
553                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
554                                                 sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
555
556                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
557                 }
558                 else
559                 {
560                         if (ADHOC_ON(pAd))
561                         {
562                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
563                                 LinkDown(pAd, FALSE);
564                                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
565                                 pAd->IndicateMediaState = NdisMediaStateDisconnected;
566                                 RTMP_IndicateMediaState(pAd);
567                 pAd->ExtraInfo = GENERAL_LINK_DOWN;
568                                 DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
569                         }
570
571                         // Change the wepstatus to original wepstatus
572                         pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
573                         pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
574                         pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
575
576                         // Check cipher suite, AP must have more secured cipher than station setting
577                         // Set the Pairwise and Group cipher to match the intended AP setting
578                         // We can only connect to AP with less secured cipher setting
579                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
580                         {
581                                 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
582
583                                 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
584                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
585                                 else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
586                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
587                                 else    // There is no PairCipher Aux, downgrade our capability to TKIP
588                                         pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
589                         }
590                         else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
591                         {
592                                 pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
593
594                                 if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
595                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
596                                 else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
597                                         pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
598                                 else    // There is no PairCipher Aux, downgrade our capability to TKIP
599                                         pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
600
601                                 // RSN capability
602                                 pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
603                         }
604
605                         // Set Mix cipher flag
606                         pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
607                         if (pAd->StaCfg.bMixCipher == TRUE)
608                         {
609                                 // If mix cipher, re-build RSNIE
610                                 RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
611                         }
612                         // No active association, join the BSS immediately
613                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
614                                 pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
615
616                         JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
617                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
618
619                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
620                 }
621         }
622 }
623
624 // Roaming is the only external request triggering CNTL state machine
625 // despite of other "SET OID" operation. All "SET OID" related oerations
626 // happen in sequence, because no other SET OID will be sent to this device
627 // until the the previous SET operation is complete (successful o failed).
628 // So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
629 // or been corrupted by other "SET OID"?
630 //
631 // IRQL = DISPATCH_LEVEL
632 VOID CntlMlmeRoamingProc(
633         IN PRTMP_ADAPTER pAd,
634         IN MLME_QUEUE_ELEM *Elem)
635 {
636         // TODO:
637         // AP in different channel may show lower RSSI than actual value??
638         // should we add a weighting factor to compensate it?
639         DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
640
641         NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
642         pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
643
644         BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
645         pAd->MlmeAux.BssIdx = 0;
646         IterateOnBssTab(pAd);
647 }
648
649 /*
650         ==========================================================================
651         Description:
652
653         IRQL = DISPATCH_LEVEL
654
655         ==========================================================================
656 */
657 VOID CntlWaitDisassocProc(
658         IN PRTMP_ADAPTER pAd,
659         IN MLME_QUEUE_ELEM *Elem)
660 {
661         MLME_START_REQ_STRUCT     StartReq;
662
663         if (Elem->MsgType == MT2_DISASSOC_CONF)
664         {
665                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
666
667             if (pAd->CommonCfg.bWirelessEvent)
668                 {
669                         RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
670                 }
671
672                 LinkDown(pAd, FALSE);
673
674                 // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
675                 if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
676                 {
677                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
678                         StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
679                         MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
680                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
681                 }
682                 // case 2. try each matched BSS
683                 else
684                 {
685                         pAd->MlmeAux.BssIdx = 0;
686
687                         IterateOnBssTab(pAd);
688                 }
689         }
690 }
691
692 /*
693         ==========================================================================
694         Description:
695
696         IRQL = DISPATCH_LEVEL
697
698         ==========================================================================
699 */
700 VOID CntlWaitJoinProc(
701         IN PRTMP_ADAPTER pAd,
702         IN MLME_QUEUE_ELEM *Elem)
703 {
704         USHORT                      Reason;
705         MLME_AUTH_REQ_STRUCT        AuthReq;
706
707         if (Elem->MsgType == MT2_JOIN_CONF)
708         {
709                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
710                 if (Reason == MLME_SUCCESS)
711                 {
712                         // 1. joined an IBSS, we are pretty much done here
713                         if (pAd->MlmeAux.BssType == BSS_ADHOC)
714                         {
715                             //
716                                 // 5G bands rules of Japan:
717                                 // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
718                                 //
719                                 if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
720                       RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
721                                    )
722                                 {
723                                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
724                                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
725                                         return;
726                                 }
727
728                                 LinkUp(pAd, BSS_ADHOC);
729                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
730                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
731                                 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
732                                 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
733
734                 pAd->IndicateMediaState = NdisMediaStateConnected;
735                 pAd->ExtraInfo = GENERAL_LINK_UP;
736                         }
737                         // 2. joined a new INFRA network, start from authentication
738                         else
739                         {
740 #ifdef LEAP_SUPPORT
741                                 // Add AuthMode "LEAP" for CCX 1.X
742                                 if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
743                                 {
744                                         AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
745                                 }
746                                 else
747 #endif // LEAP_SUPPORT //
748                                 {
749                                         // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
750                                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
751                                                 (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
752                                         {
753                                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
754                                         }
755                                         else
756                                         {
757                                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
758                                         }
759                                 }
760                                 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
761                                                         sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
762
763                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
764                         }
765                 }
766                 else
767                 {
768                         // 3. failed, try next BSS
769                         pAd->MlmeAux.BssIdx++;
770                         IterateOnBssTab(pAd);
771                 }
772         }
773 }
774
775
776 /*
777         ==========================================================================
778         Description:
779
780         IRQL = DISPATCH_LEVEL
781
782         ==========================================================================
783 */
784 VOID CntlWaitStartProc(
785         IN PRTMP_ADAPTER pAd,
786         IN MLME_QUEUE_ELEM *Elem)
787 {
788         USHORT      Result;
789
790         if (Elem->MsgType == MT2_START_CONF)
791         {
792                 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
793                 if (Result == MLME_SUCCESS)
794                 {
795                     //
796                         // 5G bands rules of Japan:
797                         // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
798                         //
799                         if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
800                   RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
801                            )
802                         {
803                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
804                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
805                                 return;
806                         }
807 #ifdef DOT11_N_SUPPORT
808                         if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
809                         {
810                                 N_ChannelCheck(pAd);
811                                 SetCommonHT(pAd);
812                                 NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
813                                 RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
814                                 pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
815                                 NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
816                                 NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
817                                 COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
818
819                                 if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
820                                         (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
821                                 {
822                                         pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
823                                 }
824                                 else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
825                                                  (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
826                                 {
827                                         pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
828                                 }
829                         }
830                         else
831 #endif // DOT11_N_SUPPORT //
832                         {
833                                 pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
834                         }
835                         LinkUp(pAd, BSS_ADHOC);
836                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
837                         // Before send beacon, driver need do radar detection
838                         if ((pAd->CommonCfg.Channel > 14 )
839                                 && (pAd->CommonCfg.bIEEE80211H == 1)
840                                 && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
841                         {
842                                 pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
843                                 pAd->CommonCfg.RadarDetect.RDCount = 0;
844                         }
845
846                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
847                                 pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
848                                 pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
849                 }
850                 else
851                 {
852                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
853                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
854                 }
855         }
856 }
857
858 /*
859         ==========================================================================
860         Description:
861
862         IRQL = DISPATCH_LEVEL
863
864         ==========================================================================
865 */
866 VOID CntlWaitAuthProc(
867         IN PRTMP_ADAPTER pAd,
868         IN MLME_QUEUE_ELEM *Elem)
869 {
870         USHORT                       Reason;
871         MLME_ASSOC_REQ_STRUCT        AssocReq;
872         MLME_AUTH_REQ_STRUCT         AuthReq;
873
874         if (Elem->MsgType == MT2_AUTH_CONF)
875         {
876                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
877                 if (Reason == MLME_SUCCESS)
878                 {
879                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
880                         AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
881                                                   ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
882
883 #ifdef LEAP_SUPPORT
884                         //
885                         // Cisco Leap CCKM supported Re-association.
886                         //
887                         if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
888                         {
889                                 //if CCKM is turn on , that's mean Fast Reauthentication
890                                 //Use CCKM Reassociation instead of normal association for Fast Roaming.
891                                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
892                                                         sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
893
894                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
895                         }
896                         else
897 #endif // LEAP_SUPPORT //
898                         {
899                                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
900                                                         sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
901
902                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
903                         }
904                 }
905                 else
906                 {
907                         // This fail may because of the AP already keep us in its MAC table without
908                         // ageing-out. The previous authentication attempt must have let it remove us.
909                         // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
910                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
911 #ifdef LEAP_SUPPORT
912                         //Add AuthMode "LEAP" for CCX 1.X
913                         if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
914                         {
915                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
916                         }
917                         else
918 #endif // LEAP_SUPPORT //
919                         {
920                                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
921                                         (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
922                                 {
923                                         // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
924                                         AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
925                                 }
926                                 else
927                                 {
928                                         AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
929                                 }
930                         }
931                         MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
932                                                 sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
933
934                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
935                 }
936         }
937 }
938
939 /*
940         ==========================================================================
941         Description:
942
943         IRQL = DISPATCH_LEVEL
944
945         ==========================================================================
946 */
947 VOID CntlWaitAuthProc2(
948         IN PRTMP_ADAPTER pAd,
949         IN MLME_QUEUE_ELEM *Elem)
950 {
951         USHORT                       Reason;
952         MLME_ASSOC_REQ_STRUCT        AssocReq;
953         MLME_AUTH_REQ_STRUCT         AuthReq;
954
955         if (Elem->MsgType == MT2_AUTH_CONF)
956         {
957                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
958                 if (Reason == MLME_SUCCESS)
959                 {
960                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
961                         AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
962                                                   ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
963                         MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
964                                                 sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
965
966                         pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
967                 }
968                 else
969                 {
970 #ifdef LEAP_SUPPORT
971                         // Process LEAP first, since it use different control variable
972                         // We don't want to affect other poven operation
973                         if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
974                         {
975                                 // LEAP Auth not success, try next BSS
976                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
977                                 DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
978                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
979                                 pAd->MlmeAux.BssIdx++;
980                                 IterateOnBssTab(pAd);
981                         }
982                         else
983 #endif // LEAP_SUPPORT //
984                         if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
985                                  (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
986                         {
987                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
988                                 AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
989                                 MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
990                                                         sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
991
992                                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
993                         }
994                         else
995                         {
996                                 // not success, try next BSS
997                                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
998                                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
999                                 pAd->MlmeAux.BssIdx++;
1000                                 IterateOnBssTab(pAd);
1001                         }
1002                 }
1003         }
1004 }
1005
1006 /*
1007         ==========================================================================
1008         Description:
1009
1010         IRQL = DISPATCH_LEVEL
1011
1012         ==========================================================================
1013 */
1014 VOID CntlWaitAssocProc(
1015         IN PRTMP_ADAPTER pAd,
1016         IN MLME_QUEUE_ELEM *Elem)
1017 {
1018         USHORT      Reason;
1019
1020         if (Elem->MsgType == MT2_ASSOC_CONF)
1021         {
1022                 NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
1023                 if (Reason == MLME_SUCCESS)
1024                 {
1025                         LinkUp(pAd, BSS_INFRA);
1026                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1027                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1028
1029                         if (pAd->CommonCfg.bWirelessEvent)
1030                         {
1031                                 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1032                         }
1033                 }
1034                 else
1035                 {
1036                         // not success, try next BSS
1037                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
1038                         pAd->MlmeAux.BssIdx++;
1039                         IterateOnBssTab(pAd);
1040                 }
1041         }
1042 }
1043
1044 /*
1045         ==========================================================================
1046         Description:
1047
1048         IRQL = DISPATCH_LEVEL
1049
1050         ==========================================================================
1051 */
1052 VOID CntlWaitReassocProc(
1053         IN PRTMP_ADAPTER pAd,
1054         IN MLME_QUEUE_ELEM *Elem)
1055 {
1056         USHORT      Result;
1057
1058         if (Elem->MsgType == MT2_REASSOC_CONF)
1059         {
1060                 NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
1061                 if (Result == MLME_SUCCESS)
1062                 {
1063                         //
1064                         // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
1065                         //
1066                         LinkUp(pAd, BSS_INFRA);
1067
1068                         // send wireless event - for association
1069                         if (pAd->CommonCfg.bWirelessEvent)
1070                                 RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1071
1072
1073 #ifdef LEAP_SUPPORT
1074                         if (LEAP_CCKM_ON(pAd))
1075                         {
1076                                 STA_PORT_SECURED(pAd);
1077                                 pAd->StaCfg.WpaState = SS_FINISH;
1078                         }
1079 #endif // LEAP_SUPPORT //
1080                         pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
1081                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1082                 }
1083                 else
1084                 {
1085                         // reassoc failed, try to pick next BSS in the BSS Table
1086                         DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
1087                         pAd->MlmeAux.RoamIdx++;
1088                         IterateOnBssTab2(pAd);
1089                 }
1090         }
1091 }
1092
1093 /*
1094         ==========================================================================
1095         Description:
1096
1097         IRQL = DISPATCH_LEVEL
1098
1099         ==========================================================================
1100 */
1101 VOID LinkUp(
1102         IN PRTMP_ADAPTER pAd,
1103         IN UCHAR BssType)
1104 {
1105         ULONG   Now;
1106         UINT32  Data;
1107         BOOLEAN Cancelled;
1108         UCHAR   Value = 0, idx;
1109         MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
1110
1111         if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
1112         {
1113                 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
1114                 RTMPusecDelay(6000);
1115                 pAd->bPCIclkOff = FALSE;
1116         }
1117
1118         pEntry = &pAd->MacTab.Content[BSSID_WCID];
1119
1120         //
1121         // ASSOC - DisassocTimeoutAction
1122         // CNTL - Dis-associate successful
1123         // !!! LINK DOWN !!!
1124         // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
1125         //
1126         // To prevent DisassocTimeoutAction to call Link down after we link up,
1127         // cancel the DisassocTimer no matter what it start or not.
1128         //
1129         RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer,  &Cancelled);
1130
1131         COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1132
1133 #ifdef DOT11_N_SUPPORT
1134         COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
1135 #endif // DOT11_N_SUPPORT //
1136         // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
1137         // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
1138         // to examine if cipher algorithm switching is required.
1139         //rt2860b. Don't know why need this
1140         SwitchBetweenWepAndCkip(pAd);
1141
1142         // Before power save before link up function, We will force use 1R.
1143         // So after link up, check Rx antenna # again.
1144         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1145         if(pAd->Antenna.field.RxPath == 3)
1146         {
1147                 Value |= (0x10);
1148         }
1149         else if(pAd->Antenna.field.RxPath == 2)
1150         {
1151                 Value |= (0x8);
1152         }
1153         else if(pAd->Antenna.field.RxPath == 1)
1154         {
1155                 Value |= (0x0);
1156         }
1157         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1158         pAd->StaCfg.BBPR3 = Value;
1159
1160         if (BssType == BSS_ADHOC)
1161         {
1162                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1163                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1164
1165                 DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
1166         }
1167         else
1168         {
1169                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
1170                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1171
1172                 DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
1173         }
1174
1175         // 3*3
1176         // reset Tx beamforming bit
1177         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1178         Value &= (~0x01);
1179         Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
1180         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1181
1182 #ifdef DOT11_N_SUPPORT
1183         // Change to AP channel
1184     if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1185         {
1186                 // Must using 40MHz.
1187                 pAd->CommonCfg.BBPCurrentBW = BW_40;
1188                 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1189                 AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1190
1191                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1192                 Value &= (~0x18);
1193                 Value |= 0x10;
1194                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1195
1196                 //  RX : control channel at lower
1197                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1198                 Value &= (~0x20);
1199                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1200         pAd->StaCfg.BBPR3 = Value;
1201
1202                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1203                 Data &= 0xfffffffe;
1204                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1205
1206                 if (pAd->MACVersion == 0x28600100)
1207                 {
1208                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1209                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1210                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1211             DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1212                 }
1213
1214                 DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
1215         }
1216         else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
1217     {
1218             // Must using 40MHz.
1219                 pAd->CommonCfg.BBPCurrentBW = BW_40;
1220                 AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
1221             AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
1222
1223                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1224                 Value &= (~0x18);
1225                 Value |= 0x10;
1226                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1227
1228                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1229                 Data |= 0x1;
1230                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1231
1232                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1233             Value |= (0x20);
1234                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1235         pAd->StaCfg.BBPR3 = Value;
1236
1237                 if (pAd->MACVersion == 0x28600100)
1238                 {
1239                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
1240                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
1241                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
1242                             DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1243                 }
1244
1245             DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
1246     }
1247     else
1248 #endif // DOT11_N_SUPPORT //
1249     {
1250             pAd->CommonCfg.BBPCurrentBW = BW_20;
1251                 pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
1252                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
1253                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
1254
1255                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
1256                 Value &= (~0x18);
1257                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
1258
1259                 RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
1260                 Data &= 0xfffffffe;
1261                 RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
1262
1263                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
1264                 Value &= (~0x20);
1265                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
1266         pAd->StaCfg.BBPR3 = Value;
1267
1268                 if (pAd->MACVersion == 0x28600100)
1269                 {
1270                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
1271                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
1272                         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
1273             DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
1274                 }
1275
1276             DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
1277     }
1278
1279         RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
1280         //
1281         // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
1282         //
1283         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
1284
1285         DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
1286                 BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
1287
1288 #ifdef DOT11_N_SUPPORT
1289         DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
1290 #endif // DOT11_N_SUPPORT //
1291
1292                 AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
1293
1294         AsicSetSlotTime(pAd, TRUE);
1295         AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
1296
1297         // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
1298         AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
1299
1300 #ifdef DOT11_N_SUPPORT
1301         if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
1302         {
1303                 // Update HT protectionfor based on AP's operating mode.
1304         if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
1305         {
1306                 AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, TRUE);
1307         }
1308         else
1309                         AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode,  ALLN_SETPROTECT, FALSE, FALSE);
1310         }
1311 #endif // DOT11_N_SUPPORT //
1312
1313         NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
1314
1315         NdisGetSystemUpTime(&Now);
1316         pAd->StaCfg.LastBeaconRxTime = Now;   // last RX timestamp
1317
1318         if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
1319                 CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
1320         {
1321                 MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
1322         }
1323
1324         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1325
1326         if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
1327         {
1328         }
1329         pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
1330
1331         if (BssType == BSS_ADHOC)
1332         {
1333                 MakeIbssBeacon(pAd);
1334                 if ((pAd->CommonCfg.Channel > 14)
1335                         && (pAd->CommonCfg.bIEEE80211H == 1)
1336                         && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
1337                 {
1338                         ; //Do nothing
1339                 }
1340                 else
1341                 {
1342                         AsicEnableIbssSync(pAd);
1343                 }
1344
1345                 // In ad hoc mode, use MAC table from index 1.
1346                 // p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
1347                 RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
1348                 RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
1349
1350                 // If WEP is enabled, add key material and cipherAlg into Asic
1351                 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1352
1353                 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1354                 {
1355                         PUCHAR  Key;
1356                         UCHAR   CipherAlg;
1357
1358                         for (idx=0; idx < SHARE_KEY_NUM; idx++)
1359                 {
1360                                 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1361                         Key = pAd->SharedKey[BSS0][idx].Key;
1362
1363                                 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1364                                 {
1365                                         // Set key material and cipherAlg to Asic
1366                                 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1367
1368                     if (idx == pAd->StaCfg.DefaultKeyId)
1369                                         {
1370                                                 // Update WCID attribute table and IVEIV table for this group key table
1371                                                 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1372                                         }
1373                                 }
1374
1375
1376                         }
1377                 }
1378                 // If WPANone is enabled, add key material and cipherAlg into Asic
1379                 // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
1380                 else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1381                 {
1382                         pAd->StaCfg.DefaultKeyId = 0;   // always be zero
1383
1384             NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
1385                                                         pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
1386                         NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
1387
1388             if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1389             {
1390                         NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
1391                         NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
1392             }
1393
1394                         // Decide its ChiperAlg
1395                         if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
1396                                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
1397                         else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
1398                                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1399                         else
1400             {
1401                 DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
1402                                 pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
1403             }
1404
1405                         // Set key material and cipherAlg to Asic
1406                         AsicAddSharedKeyEntry(pAd,
1407                                                                   BSS0,
1408                                                                   0,
1409                                                                   pAd->SharedKey[BSS0][0].CipherAlg,
1410                                                                   pAd->SharedKey[BSS0][0].Key,
1411                                                                   pAd->SharedKey[BSS0][0].TxMic,
1412                                                                   pAd->SharedKey[BSS0][0].RxMic);
1413
1414             // Update WCID attribute table and IVEIV table for this group key table
1415                         RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
1416
1417                 }
1418
1419         }
1420         else // BSS_INFRA
1421         {
1422                 // Check the new SSID with last SSID
1423                 while (Cancelled == TRUE)
1424                 {
1425                         if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
1426                         {
1427                                 if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
1428                                 {
1429                                         // Link to the old one no linkdown is required.
1430                                         break;
1431                                 }
1432                         }
1433                         // Send link down event before set to link up
1434                         pAd->IndicateMediaState = NdisMediaStateDisconnected;
1435                         RTMP_IndicateMediaState(pAd);
1436             pAd->ExtraInfo = GENERAL_LINK_DOWN;
1437                         DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
1438                         break;
1439                 }
1440
1441                 //
1442                 // On WPA mode, Remove All Keys if not connect to the last BSSID
1443                 // Key will be set after 4-way handshake.
1444                 //
1445                 if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1446                 {
1447                         ULONG           IV;
1448
1449                         // Remove all WPA keys
1450                         RTMPWPARemoveAllKeys(pAd);
1451                         pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1452                         pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1453
1454                         // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
1455                         // If IV related values are too large in GroupMsg2, AP would ignore this message.
1456                         IV = 0;
1457                         IV |= (pAd->StaCfg.DefaultKeyId << 30);
1458                         AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
1459
1460                         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1461                 }
1462                 // NOTE:
1463                 // the decision of using "short slot time" or not may change dynamically due to
1464                 // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1465
1466                 // NOTE:
1467                 // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
1468                 // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
1469
1470                 ComposePsPoll(pAd);
1471                 ComposeNullFrame(pAd);
1472
1473                         AsicEnableBssSync(pAd);
1474
1475                 // Add BSSID to WCID search table
1476                 AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
1477
1478                 NdisAcquireSpinLock(&pAd->MacTabLock);
1479                 // add this BSSID entry into HASH table
1480                 {
1481                         UCHAR HashIdx;
1482
1483                         //pEntry = &pAd->MacTab.Content[BSSID_WCID];
1484                         HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
1485                         if (pAd->MacTab.Hash[HashIdx] == NULL)
1486                         {
1487                                 pAd->MacTab.Hash[HashIdx] = pEntry;
1488                         }
1489                         else
1490                         {
1491                                 pCurrEntry = pAd->MacTab.Hash[HashIdx];
1492                                 while (pCurrEntry->pNext != NULL)
1493                                         pCurrEntry = pCurrEntry->pNext;
1494                                 pCurrEntry->pNext = pEntry;
1495                         }
1496                 }
1497                 NdisReleaseSpinLock(&pAd->MacTabLock);
1498
1499
1500                 // If WEP is enabled, add paiewise and shared key
1501 #ifdef WPA_SUPPLICANT_SUPPORT
1502         if (((pAd->StaCfg.WpaSupplicantUP)&&
1503              (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
1504              (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
1505             ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
1506               (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
1507 #else
1508                 if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
1509 #endif // WPA_SUPPLICANT_SUPPORT //
1510                 {
1511                         PUCHAR  Key;
1512                         UCHAR   CipherAlg;
1513
1514                         for (idx=0; idx < SHARE_KEY_NUM; idx++)
1515                 {
1516                                 CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
1517                         Key = pAd->SharedKey[BSS0][idx].Key;
1518
1519                                 if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
1520                                 {
1521                                         // Set key material and cipherAlg to Asic
1522                                 AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
1523
1524                                         if (idx == pAd->StaCfg.DefaultKeyId)
1525                                         {
1526                                                 // Assign group key info
1527                                                 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
1528
1529                                                 // Assign pairwise key info
1530                                                 RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
1531                                         }
1532                                 }
1533                         }
1534                 }
1535
1536                 // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
1537                 // should wait until at least 2 active nodes in this BSSID.
1538                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1539
1540         // For GUI ++
1541                 if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
1542                 {
1543                         pAd->IndicateMediaState = NdisMediaStateConnected;
1544                         pAd->ExtraInfo = GENERAL_LINK_UP;
1545                 }
1546         // --
1547                 RTMP_IndicateMediaState(pAd);
1548
1549                 // Add BSSID in my MAC Table.
1550         NdisAcquireSpinLock(&pAd->MacTabLock);
1551                 RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1552                 pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
1553                 pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
1554                 pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE;      //Although this is bssid..still set ValidAsCl
1555                 pAd->MacTab.Size = 1;   // infra mode always set MACtab size =1.
1556                 pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
1557                 pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
1558                 pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
1559         NdisReleaseSpinLock(&pAd->MacTabLock);
1560
1561                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!!  ClientStatusFlags=%lx)\n",
1562                         pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1563
1564                 MlmeUpdateTxRates(pAd, TRUE, BSS0);
1565 #ifdef DOT11_N_SUPPORT
1566                 MlmeUpdateHtTxRates(pAd, BSS0);
1567                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
1568 #endif // DOT11_N_SUPPORT //
1569
1570                 //
1571                 // Report Adjacent AP report.
1572                 //
1573 #ifdef LEAP_SUPPORT
1574                 CCXAdjacentAPReport(pAd);
1575 #endif // LEAP_SUPPORT //
1576
1577                 if (pAd->CommonCfg.bAggregationCapable)
1578                 {
1579                         if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
1580                         {
1581
1582                                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
1583                                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1584                 RTMPSetPiggyBack(pAd, TRUE);
1585                                 DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
1586                         }
1587                         else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
1588                         {
1589                                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1590                         }
1591                 }
1592
1593                 if (pAd->MlmeAux.APRalinkIe != 0x0)
1594                 {
1595 #ifdef DOT11_N_SUPPORT
1596                         if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
1597                         {
1598                                 AsicEnableRDG(pAd);
1599                         }
1600 #endif // DOT11_N_SUPPORT //
1601                         OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1602                         CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1603                 }
1604                 else
1605                 {
1606                         OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
1607                         CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
1608                 }
1609         }
1610
1611 #ifdef DOT11_N_SUPPORT
1612         DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
1613 #endif // DOT11_N_SUPPORT //
1614
1615         // Set LED
1616         RTMPSetLED(pAd, LED_LINK_UP);
1617
1618         pAd->Mlme.PeriodicRound = 0;
1619         pAd->Mlme.OneSecPeriodicRound = 0;
1620         pAd->bConfigChanged = FALSE;        // Reset config flag
1621         pAd->ExtraInfo = GENERAL_LINK_UP;   // Update extra information to link is up
1622
1623         // Set asic auto fall back
1624         {
1625                 PUCHAR                                  pTable;
1626                 UCHAR                                   TableSize = 0;
1627
1628                 MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
1629                 AsicUpdateAutoFallBackTable(pAd, pTable);
1630         }
1631
1632         NdisAcquireSpinLock(&pAd->MacTabLock);
1633     pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1634     pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
1635         if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
1636         {
1637                 pEntry->bAutoTxRateSwitch = FALSE;
1638 #ifdef DOT11_N_SUPPORT
1639                 if (pEntry->HTPhyMode.field.MCS == 32)
1640                         pEntry->HTPhyMode.field.ShortGI = GI_800;
1641
1642                 if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
1643                         pEntry->HTPhyMode.field.STBC = STBC_NONE;
1644 #endif // DOT11_N_SUPPORT //
1645                 // If the legacy mode is set, overwrite the transmit setting of this entry.
1646                 if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
1647                         RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
1648         }
1649         else
1650                 pEntry->bAutoTxRateSwitch = TRUE;
1651         NdisReleaseSpinLock(&pAd->MacTabLock);
1652
1653         //  Let Link Status Page display first initial rate.
1654         pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
1655         // Select DAC according to HT or Legacy
1656         if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
1657         {
1658                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1659                 Value &= (~0x18);
1660                 if (pAd->Antenna.field.TxPath == 2)
1661                 {
1662                     Value |= 0x10;
1663                 }
1664                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1665         }
1666         else
1667         {
1668                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
1669                 Value &= (~0x18);
1670                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
1671         }
1672
1673 #ifdef DOT11_N_SUPPORT
1674         if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
1675         {
1676         }
1677         else if (pEntry->MaxRAmpduFactor == 0)
1678         {
1679             // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
1680             // Because our Init value is 1 at MACRegTable.
1681                 RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
1682         }
1683 #endif // DOT11_N_SUPPORT //
1684
1685         // Patch for Marvel AP to gain high throughput
1686         // Need to set as following,
1687         // 1. Set txop in register-EDCA_AC0_CFG as 0x60
1688         // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
1689         // 3. PBF_MAX_PCNT as 0x1F3FBF9F
1690         // 4. kick per two packets when dequeue
1691         //
1692         // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
1693         //
1694         // if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is.
1695 #ifdef DOT11_N_SUPPORT
1696         if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
1697                 || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))
1698         {
1699                 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1700                 Data  &= 0xFFFFFF00;
1701                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1702
1703                 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1704                 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
1705         }
1706         else
1707 #endif // DOT11_N_SUPPORT //
1708         if (pAd->CommonCfg.bEnableTxBurst)
1709         {
1710                 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1711                 Data  &= 0xFFFFFF00;
1712                 Data  |= 0x60;
1713                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1714                 pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
1715
1716                 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
1717                 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
1718         }
1719         else
1720         {
1721                 RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
1722                 Data  &= 0xFFFFFF00;
1723                 RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
1724
1725                 RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
1726                 DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
1727         }
1728
1729 #ifdef DOT11_N_SUPPORT
1730         // Re-check to turn on TX burst or not.
1731         if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
1732         {
1733                 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
1734                 if (pAd->CommonCfg.bEnableTxBurst)
1735                 {
1736                     UINT32 MACValue = 0;
1737                         // Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too.
1738                         // I didn't change PBF_MAX_PCNT setting.
1739                         RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
1740                         MACValue  &= 0xFFFFFF00;
1741                         RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
1742                         pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
1743                 }
1744         }
1745         else
1746         {
1747                 pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
1748         }
1749 #endif // DOT11_N_SUPPORT //
1750
1751         pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
1752         COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1753         DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
1754         // BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
1755         // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
1756         // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
1757
1758     if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
1759     {
1760         pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1761                 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
1762         }
1763
1764         NdisAcquireSpinLock(&pAd->MacTabLock);
1765         pEntry->PortSecured = pAd->StaCfg.PortSecured;
1766         NdisReleaseSpinLock(&pAd->MacTabLock);
1767
1768     //
1769         // Patch Atheros AP TX will breakdown issue.
1770         // AP Model: DLink DWL-8200AP
1771         //
1772         if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
1773         {
1774                 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
1775         }
1776         else
1777         {
1778                 RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
1779         }
1780
1781         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
1782         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1783
1784 #ifdef DOT11_N_SUPPORT
1785 #ifdef DOT11N_DRAFT3
1786         if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
1787         {
1788                 OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
1789                 BuildEffectedChannelList(pAd);
1790         }
1791 #endif // DOT11N_DRAFT3 //
1792 #endif // DOT11_N_SUPPORT //
1793 }
1794
1795 /*
1796         ==========================================================================
1797
1798         Routine Description:
1799                 Disconnect current BSSID
1800
1801         Arguments:
1802                 pAd                             - Pointer to our adapter
1803                 IsReqFromAP             - Request from AP
1804
1805         Return Value:
1806                 None
1807
1808         IRQL = DISPATCH_LEVEL
1809
1810         Note:
1811                 We need more information to know it's this requst from AP.
1812                 If yes! we need to do extra handling, for example, remove the WPA key.
1813                 Otherwise on 4-way handshaking will faied, since the WPA key didn't be
1814                 remove while auto reconnect.
1815                 Disconnect request from AP, it means we will start afresh 4-way handshaking
1816                 on WPA mode.
1817
1818         ==========================================================================
1819 */
1820 VOID LinkDown(
1821         IN PRTMP_ADAPTER pAd,
1822         IN  BOOLEAN      IsReqFromAP)
1823 {
1824         UCHAR                       i, ByteValue = 0;
1825         BOOLEAN         Cancelled;
1826
1827         // Do nothing if monitor mode is on
1828         if (MONITOR_ON(pAd))
1829                 return;
1830
1831         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
1832         RTMPCancelTimer(&pAd->Mlme.PsPollTimer,         &Cancelled);
1833
1834         // Not allow go to sleep within linkdown function.
1835         RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
1836
1837     if (pAd->CommonCfg.bWirelessEvent)
1838         {
1839                 RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1840         }
1841
1842         DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
1843         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
1844
1845     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
1846     {
1847             BOOLEAN Cancelled;
1848         pAd->Mlme.bPsPollTimerRunning = FALSE;
1849         RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
1850     }
1851
1852     if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
1853                 RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
1854                 RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
1855     {
1856                 AsicForceWakeup(pAd, RTMP_HALT);
1857         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
1858     }
1859
1860     pAd->bPCIclkOff = FALSE;
1861         if (ADHOC_ON(pAd))              // Adhoc mode link down
1862         {
1863                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
1864
1865                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
1866                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1867                 pAd->IndicateMediaState = NdisMediaStateDisconnected;
1868                 RTMP_IndicateMediaState(pAd);
1869         pAd->ExtraInfo = GENERAL_LINK_DOWN;
1870                 BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1871                 DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
1872         }
1873         else                                    // Infra structure mode
1874         {
1875                 DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
1876
1877                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
1878                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
1879
1880                 // Saved last SSID for linkup comparison
1881                 pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
1882                 NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
1883                 COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
1884                 if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
1885                 {
1886                         pAd->IndicateMediaState = NdisMediaStateDisconnected;
1887                         RTMP_IndicateMediaState(pAd);
1888             pAd->ExtraInfo = GENERAL_LINK_DOWN;
1889                         DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
1890                         pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
1891                 }
1892                 else
1893                 {
1894             //
1895                         // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
1896                         // Otherwise lost beacon or receive De-Authentication from AP,
1897                         // then we should delete BSSID from BssTable.
1898                         // If we don't delete from entry, roaming will fail.
1899                         //
1900                         BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
1901                 }
1902
1903                 // restore back to -
1904                 //      1. long slot (20 us) or short slot (9 us) time
1905                 //      2. turn on/off RTS/CTS and/or CTS-to-self protection
1906                 //      3. short preamble
1907                 OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
1908
1909                 if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
1910                 {
1911                         //
1912                         // Record current AP's information.
1913                         // for later used reporting Adjacent AP report.
1914                         //
1915                         pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
1916                         pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
1917                         NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
1918                         COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
1919                 }
1920         }
1921
1922         for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
1923         {
1924                 if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
1925                         MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
1926         }
1927
1928         pAd->StaCfg.CCXQosECWMin        = 4;
1929         pAd->StaCfg.CCXQosECWMax        = 10;
1930
1931         AsicSetSlotTime(pAd, TRUE); //FALSE);
1932         AsicSetEdcaParm(pAd, NULL);
1933
1934         // Set LED
1935         RTMPSetLED(pAd, LED_LINK_DOWN);
1936     pAd->LedIndicatorStregth = 0xF0;
1937     RTMPSetSignalLED(pAd, -100);        // Force signal strength Led to be turned off, firmware is not done it.
1938
1939                 AsicDisableSync(pAd);
1940
1941         pAd->Mlme.PeriodicRound = 0;
1942         pAd->Mlme.OneSecPeriodicRound = 0;
1943
1944         if (pAd->StaCfg.BssType == BSS_INFRA)
1945         {
1946                 // Remove StaCfg Information after link down
1947                 NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
1948                 NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
1949                 pAd->CommonCfg.SsidLen = 0;
1950         }
1951 #ifdef DOT11_N_SUPPORT
1952         NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
1953         NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
1954         pAd->MlmeAux.HtCapabilityLen = 0;
1955         pAd->MlmeAux.NewExtChannelOffset = 0xff;
1956 #endif // DOT11_N_SUPPORT //
1957
1958         // Reset WPA-PSK state. Only reset when supplicant enabled
1959         if (pAd->StaCfg.WpaState != SS_NOTUSE)
1960         {
1961                 pAd->StaCfg.WpaState = SS_START;
1962                 // Clear Replay counter
1963                 NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
1964         }
1965
1966
1967         //
1968         // if link down come from AP, we need to remove all WPA keys on WPA mode.
1969         // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
1970         //
1971         if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
1972         {
1973                 // Remove all WPA keys
1974                 RTMPWPARemoveAllKeys(pAd);
1975         }
1976
1977         // 802.1x port control
1978 #ifdef WPA_SUPPLICANT_SUPPORT
1979         // Prevent clear PortSecured here with static WEP
1980         // NetworkManger set security policy first then set SSID to connect AP.
1981         if (pAd->StaCfg.WpaSupplicantUP &&
1982                 (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
1983                 (pAd->StaCfg.IEEE8021X == FALSE))
1984         {
1985                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
1986         }
1987         else
1988 #endif // WPA_SUPPLICANT_SUPPORT //
1989         {
1990                 pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1991                 pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
1992         }
1993
1994         NdisAcquireSpinLock(&pAd->MacTabLock);
1995         pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
1996         NdisReleaseSpinLock(&pAd->MacTabLock);
1997
1998         pAd->StaCfg.MicErrCnt = 0;
1999
2000         // Turn off Ckip control flag
2001         pAd->StaCfg.bCkipOn = FALSE;
2002         pAd->StaCfg.CCXEnable = FALSE;
2003
2004     pAd->IndicateMediaState = NdisMediaStateDisconnected;
2005         // Update extra information to link is up
2006         pAd->ExtraInfo = GENERAL_LINK_DOWN;
2007
2008     pAd->StaCfg.AdhocBOnlyJoined = FALSE;
2009         pAd->StaCfg.AdhocBGJoined = FALSE;
2010         pAd->StaCfg.Adhoc20NJoined = FALSE;
2011     pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
2012
2013         // Reset the Current AP's IP address
2014         NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
2015
2016         // Clean association information
2017         NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
2018         pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
2019         pAd->StaCfg.ReqVarIELen = 0;
2020         pAd->StaCfg.ResVarIELen = 0;
2021
2022         //
2023         // Reset RSSI value after link down
2024         //
2025         pAd->StaCfg.RssiSample.AvgRssi0 = 0;
2026         pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
2027         pAd->StaCfg.RssiSample.AvgRssi1 = 0;
2028         pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
2029         pAd->StaCfg.RssiSample.AvgRssi2 = 0;
2030         pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
2031
2032         // Restore MlmeRate
2033         pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
2034         pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
2035
2036 #ifdef DOT11_N_SUPPORT
2037         //
2038         // After Link down, reset piggy-back setting in ASIC. Disable RDG.
2039         //
2040         if (pAd->CommonCfg.BBPCurrentBW == BW_40)
2041         {
2042                 pAd->CommonCfg.BBPCurrentBW = BW_20;
2043                 RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
2044                 ByteValue &= (~0x18);
2045                 RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
2046         }
2047 #endif // DOT11_N_SUPPORT //
2048         // Reset DAC
2049         RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
2050         ByteValue &= (~0x18);
2051         if (pAd->Antenna.field.TxPath == 2)
2052         {
2053                 ByteValue |= 0x10;
2054         }
2055         RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
2056
2057         RTMPSetPiggyBack(pAd,FALSE);
2058         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
2059
2060 #ifdef DOT11_N_SUPPORT
2061         pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
2062 #endif // DOT11_N_SUPPORT //
2063
2064         // Restore all settings in the following.
2065         AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
2066         AsicDisableRDG(pAd);
2067         pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
2068         pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
2069
2070 #ifdef DOT11_N_SUPPORT
2071 #ifdef DOT11N_DRAFT3
2072         OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
2073         pAd->CommonCfg.BSSCoexist2040.word = 0;
2074         TriEventInit(pAd);
2075         for (i = 0; i < (pAd->ChannelListNum - 1); i++)
2076         {
2077                 pAd->ChannelList[i].bEffectedChannel = FALSE;
2078         }
2079 #endif // DOT11N_DRAFT3 //
2080 #endif // DOT11_N_SUPPORT //
2081
2082         RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
2083         RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
2084
2085         // Allow go to sleep after linkdown steps.
2086         RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
2087
2088 #ifdef WPA_SUPPLICANT_SUPPORT
2089 #ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
2090         if (pAd->StaCfg.WpaSupplicantUP) {
2091                 union iwreq_data    wrqu;
2092                 //send disassociate event to wpa_supplicant
2093                 memset(&wrqu, 0, sizeof(wrqu));
2094                 wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
2095                 wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
2096         }
2097 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2098 #endif // WPA_SUPPLICANT_SUPPORT //
2099
2100 #ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
2101         {
2102                 union iwreq_data    wrqu;
2103                 memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
2104                 wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
2105         }
2106 #endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
2107 }
2108
2109 /*
2110         ==========================================================================
2111         Description:
2112
2113         IRQL = DISPATCH_LEVEL
2114
2115         ==========================================================================
2116 */
2117 VOID IterateOnBssTab(
2118         IN PRTMP_ADAPTER pAd)
2119 {
2120         MLME_START_REQ_STRUCT   StartReq;
2121         MLME_JOIN_REQ_STRUCT    JoinReq;
2122         ULONG                   BssIdx;
2123
2124         // Change the wepstatus to original wepstatus
2125         pAd->StaCfg.WepStatus   = pAd->StaCfg.OrigWepStatus;
2126         pAd->StaCfg.PairCipher  = pAd->StaCfg.OrigWepStatus;
2127         pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
2128
2129         BssIdx = pAd->MlmeAux.BssIdx;
2130         if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
2131         {
2132                 // Check cipher suite, AP must have more secured cipher than station setting
2133                 // Set the Pairwise and Group cipher to match the intended AP setting
2134                 // We can only connect to AP with less secured cipher setting
2135                 if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
2136                 {
2137                         pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
2138
2139                         if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
2140                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
2141                         else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
2142                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
2143                         else    // There is no PairCipher Aux, downgrade our capability to TKIP
2144                                 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2145                 }
2146                 else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
2147                 {
2148                         pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
2149
2150                         if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
2151                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
2152                         else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
2153                                 pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
2154                         else    // There is no PairCipher Aux, downgrade our capability to TKIP
2155                                 pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
2156
2157                         // RSN capability
2158                         pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
2159                 }
2160
2161                 // Set Mix cipher flag
2162                 pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
2163                 if (pAd->StaCfg.bMixCipher == TRUE)
2164                 {
2165                         // If mix cipher, re-build RSNIE
2166                         RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
2167                 }
2168
2169                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
2170                 JoinParmFill(pAd, &JoinReq, BssIdx);
2171                 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
2172                                         &JoinReq);
2173                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
2174         }
2175         else if (pAd->StaCfg.BssType == BSS_ADHOC)
2176         {
2177                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
2178                 StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
2179                 MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
2180                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
2181         }
2182         else // no more BSS
2183         {
2184                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
2185                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2186                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2187                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2188         }
2189 }
2190
2191 // for re-association only
2192 // IRQL = DISPATCH_LEVEL
2193 VOID IterateOnBssTab2(
2194         IN PRTMP_ADAPTER pAd)
2195 {
2196         MLME_REASSOC_REQ_STRUCT ReassocReq;
2197         ULONG                   BssIdx;
2198         BSS_ENTRY               *pBss;
2199
2200         BssIdx = pAd->MlmeAux.RoamIdx;
2201         pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
2202
2203         if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
2204         {
2205                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
2206
2207                 AsicSwitchChannel(pAd, pBss->Channel, FALSE);
2208                 AsicLockChannel(pAd, pBss->Channel);
2209
2210                 // reassociate message has the same structure as associate message
2211                 AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
2212                                           ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
2213                 MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
2214                                         sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
2215
2216                 pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
2217         }
2218         else // no more BSS
2219         {
2220                 DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
2221                 AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
2222                 AsicLockChannel(pAd, pAd->CommonCfg.Channel);
2223                 pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
2224         }
2225 }
2226
2227 /*
2228         ==========================================================================
2229         Description:
2230
2231         IRQL = DISPATCH_LEVEL
2232
2233         ==========================================================================
2234 */
2235 VOID JoinParmFill(
2236         IN PRTMP_ADAPTER pAd,
2237         IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
2238         IN ULONG BssIdx)
2239 {
2240         JoinReq->BssIdx = BssIdx;
2241 }
2242
2243 /*
2244         ==========================================================================
2245         Description:
2246
2247         IRQL = DISPATCH_LEVEL
2248
2249         ==========================================================================
2250 */
2251 VOID ScanParmFill(
2252         IN PRTMP_ADAPTER pAd,
2253         IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
2254         IN CHAR Ssid[],
2255         IN UCHAR SsidLen,
2256         IN UCHAR BssType,
2257         IN UCHAR ScanType)
2258 {
2259     NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
2260         ScanReq->SsidLen = SsidLen;
2261         NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
2262         ScanReq->BssType = BssType;
2263         ScanReq->ScanType = ScanType;
2264 }
2265
2266 /*
2267         ==========================================================================
2268         Description:
2269
2270         IRQL = DISPATCH_LEVEL
2271
2272         ==========================================================================
2273 */
2274 VOID StartParmFill(
2275         IN PRTMP_ADAPTER pAd,
2276         IN OUT MLME_START_REQ_STRUCT *StartReq,
2277         IN CHAR Ssid[],
2278         IN UCHAR SsidLen)
2279 {
2280         ASSERT(SsidLen <= MAX_LEN_OF_SSID);
2281         NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
2282         StartReq->SsidLen = SsidLen;
2283 }
2284
2285 /*
2286         ==========================================================================
2287         Description:
2288
2289         IRQL = DISPATCH_LEVEL
2290
2291         ==========================================================================
2292 */
2293 VOID AuthParmFill(
2294         IN PRTMP_ADAPTER pAd,
2295         IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
2296         IN PUCHAR pAddr,
2297         IN USHORT Alg)
2298 {
2299         COPY_MAC_ADDR(AuthReq->Addr, pAddr);
2300         AuthReq->Alg = Alg;
2301         AuthReq->Timeout = AUTH_TIMEOUT;
2302 }
2303
2304 /*
2305         ==========================================================================
2306         Description:
2307
2308         IRQL = DISPATCH_LEVEL
2309
2310         ==========================================================================
2311  */
2312 VOID ComposePsPoll(
2313         IN PRTMP_ADAPTER pAd)
2314 {
2315         NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
2316         pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
2317         pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
2318         pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
2319         COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
2320         COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
2321 }
2322
2323 // IRQL = DISPATCH_LEVEL
2324 VOID ComposeNullFrame(
2325         IN PRTMP_ADAPTER pAd)
2326 {
2327         NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
2328         pAd->NullFrame.FC.Type = BTYPE_DATA;
2329         pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
2330         pAd->NullFrame.FC.ToDs = 1;
2331         COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
2332         COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
2333         COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
2334 }
2335
2336
2337
2338
2339 /*
2340         ==========================================================================
2341         Description:
2342                 Pre-build a BEACON frame in the shared memory
2343
2344         IRQL = PASSIVE_LEVEL
2345         IRQL = DISPATCH_LEVEL
2346
2347         ==========================================================================
2348 */
2349 ULONG MakeIbssBeacon(
2350         IN PRTMP_ADAPTER pAd)
2351 {
2352         UCHAR         DsLen = 1, IbssLen = 2;
2353         UCHAR         LocalErpIe[3] = {IE_ERP, 1, 0x04};
2354         HEADER_802_11 BcnHdr;
2355         USHORT        CapabilityInfo;
2356         LARGE_INTEGER FakeTimestamp;
2357         ULONG         FrameLen = 0;
2358         PTXWI_STRUC       pTxWI = &pAd->BeaconTxWI;
2359         CHAR         *pBeaconFrame = pAd->BeaconBuf;
2360         BOOLEAN       Privacy;
2361         UCHAR         SupRate[MAX_LEN_OF_SUPPORTED_RATES];
2362         UCHAR         SupRateLen = 0;
2363         UCHAR         ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
2364         UCHAR         ExtRateLen = 0;
2365         UCHAR         RSNIe = IE_WPA;
2366
2367         if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
2368         {
2369                 SupRate[0] = 0x82; // 1 mbps
2370                 SupRate[1] = 0x84; // 2 mbps
2371                 SupRate[2] = 0x8b; // 5.5 mbps
2372                 SupRate[3] = 0x96; // 11 mbps
2373                 SupRateLen = 4;
2374                 ExtRateLen = 0;
2375         }
2376         else if (pAd->CommonCfg.Channel > 14)
2377         {
2378                 SupRate[0]  = 0x8C;    // 6 mbps, in units of 0.5 Mbps, basic rate
2379                 SupRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
2380                 SupRate[2]  = 0x98;    // 12 mbps, in units of 0.5 Mbps, basic rate
2381                 SupRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
2382                 SupRate[4]  = 0xb0;    // 24 mbps, in units of 0.5 Mbps, basic rate
2383                 SupRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
2384                 SupRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
2385                 SupRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
2386                 SupRateLen  = 8;
2387                 ExtRateLen  = 0;
2388
2389                 //
2390                 // Also Update MlmeRate & RtsRate for G only & A only
2391                 //
2392                 pAd->CommonCfg.MlmeRate = RATE_6;
2393                 pAd->CommonCfg.RtsRate = RATE_6;
2394                 pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
2395                 pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2396                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
2397                 pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
2398         }
2399         else
2400         {
2401                 SupRate[0] = 0x82; // 1 mbps
2402                 SupRate[1] = 0x84; // 2 mbps
2403                 SupRate[2] = 0x8b; // 5.5 mbps
2404                 SupRate[3] = 0x96; // 11 mbps
2405                 SupRateLen = 4;
2406
2407                 ExtRate[0]  = 0x0C;    // 6 mbps, in units of 0.5 Mbps,
2408                 ExtRate[1]  = 0x12;    // 9 mbps, in units of 0.5 Mbps
2409                 ExtRate[2]  = 0x18;    // 12 mbps, in units of 0.5 Mbps,
2410                 ExtRate[3]  = 0x24;    // 18 mbps, in units of 0.5 Mbps
2411                 ExtRate[4]  = 0x30;    // 24 mbps, in units of 0.5 Mbps,
2412                 ExtRate[5]  = 0x48;    // 36 mbps, in units of 0.5 Mbps
2413                 ExtRate[6]  = 0x60;    // 48 mbps, in units of 0.5 Mbps
2414                 ExtRate[7]  = 0x6c;    // 54 mbps, in units of 0.5 Mbps
2415                 ExtRateLen  = 8;
2416         }
2417
2418         pAd->StaActive.SupRateLen = SupRateLen;
2419         NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
2420         pAd->StaActive.ExtRateLen = ExtRateLen;
2421         NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
2422
2423         // compose IBSS beacon frame
2424         MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
2425         Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
2426                           (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
2427                           (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
2428         CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
2429
2430         MakeOutgoingFrame(pBeaconFrame,                &FrameLen,
2431                                           sizeof(HEADER_802_11),           &BcnHdr,
2432                                           TIMESTAMP_LEN,                   &FakeTimestamp,
2433                                           2,                               &pAd->CommonCfg.BeaconPeriod,
2434                                           2,                               &CapabilityInfo,
2435                                           1,                               &SsidIe,
2436                                           1,                               &pAd->CommonCfg.SsidLen,
2437                                           pAd->CommonCfg.SsidLen,          pAd->CommonCfg.Ssid,
2438                                           1,                               &SupRateIe,
2439                                           1,                               &SupRateLen,
2440                                           SupRateLen,                      SupRate,
2441                                           1,                               &DsIe,
2442                                           1,                               &DsLen,
2443                                           1,                               &pAd->CommonCfg.Channel,
2444                                           1,                               &IbssIe,
2445                                           1,                               &IbssLen,
2446                                           2,                               &pAd->StaActive.AtimWin,
2447                                           END_OF_ARGS);
2448
2449         // add ERP_IE and EXT_RAE IE of in 802.11g
2450         if (ExtRateLen)
2451         {
2452                 ULONG   tmp;
2453
2454                 MakeOutgoingFrame(pBeaconFrame + FrameLen,         &tmp,
2455                                                   3,                               LocalErpIe,
2456                                                   1,                               &ExtRateIe,
2457                                                   1,                               &ExtRateLen,
2458                                                   ExtRateLen,                      ExtRate,
2459                                                   END_OF_ARGS);
2460                 FrameLen += tmp;
2461         }
2462
2463         // If adhoc secruity is set for WPA-None, append the cipher suite IE
2464         if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
2465         {
2466                 ULONG tmp;
2467         RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
2468
2469                 MakeOutgoingFrame(pBeaconFrame + FrameLen,              &tmp,
2470                                                   1,                                    &RSNIe,
2471                                                   1,                                    &pAd->StaCfg.RSNIE_Len,
2472                                                   pAd->StaCfg.RSNIE_Len,                pAd->StaCfg.RSN_IE,
2473                                                   END_OF_ARGS);
2474                 FrameLen += tmp;
2475         }
2476
2477 #ifdef DOT11_N_SUPPORT
2478         if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
2479         {
2480                 ULONG TmpLen;
2481                 UCHAR HtLen, HtLen1;
2482
2483 #ifdef RT_BIG_ENDIAN
2484                 HT_CAPABILITY_IE HtCapabilityTmp;
2485                 ADD_HT_INFO_IE  addHTInfoTmp;
2486                 USHORT  b2lTmp, b2lTmp2;
2487 #endif
2488
2489                 // add HT Capability IE
2490                 HtLen = sizeof(pAd->CommonCfg.HtCapability);
2491                 HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
2492 #ifndef RT_BIG_ENDIAN
2493                 MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TmpLen,
2494                                                   1,                                            &HtCapIe,
2495                                                   1,                                            &HtLen,
2496                                                   HtLen,                                        &pAd->CommonCfg.HtCapability,
2497                                                   1,                                            &AddHtInfoIe,
2498                                                   1,                                            &HtLen1,
2499                                                   HtLen1,                                       &pAd->CommonCfg.AddHTInfo,
2500                                                   END_OF_ARGS);
2501 #else
2502                 NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
2503                 *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
2504                 *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
2505
2506                 NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
2507                 *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
2508                 *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
2509
2510                 MakeOutgoingFrame(pBeaconFrame+FrameLen,        &TmpLen,
2511                                                   1,                                            &HtCapIe,
2512                                                   1,                                            &HtLen,
2513                                                   HtLen,                                        &HtCapabilityTmp,
2514                                                   1,                                            &AddHtInfoIe,
2515                                                   1,                                            &HtLen1,
2516                                                   HtLen1,                                       &addHTInfoTmp,
2517                                                   END_OF_ARGS);
2518 #endif
2519                 FrameLen += TmpLen;
2520         }
2521 #endif // DOT11_N_SUPPORT //
2522
2523         //beacon use reserved WCID 0xff
2524     if (pAd->CommonCfg.Channel > 14)
2525     {
2526         RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2527                 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
2528     }
2529     else
2530     {
2531         // Set to use 1Mbps for Adhoc beacon.
2532                 HTTRANSMIT_SETTING Transmit;
2533         Transmit.word = 0;
2534         RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE,  TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
2535                 PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
2536     }
2537
2538 #ifdef RT_BIG_ENDIAN
2539         RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
2540         RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
2541 #endif
2542
2543     DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
2544                                         FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
2545         return FrameLen;
2546 }
2547
2548