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