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