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